home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2000-11-11 | 101.6 KB | 3,137 lines
## -*-Tcl-*- (install) (nowrap) # This is Metafont Mode for Alpha 7.2 or later. # If you still have Alpha 7.0 or 7.1, get Metafont Mode version 1.0 (and update soon). # # Metafont Mode is a mode for the text editor Alpha: it is designed to make # writing, processing and testing of Metafont source files much easier. # Metafont is the programming language written, as a companion to TeX, by # Donald Knuth in order to create characters, fonts, font families (and many # others things). Once Metafont mode is installed, the opening of a Metafont # source file (i-e with extension .mf) invokes a new menu (called Metafont !) # in the menu bar with the following features : # - easy insertion of all the basic Metafont commands (with electric stops) # - syntax coloring # - file marking # - capacity to process a source file from within Alpha with various flags, # printer modes, input base files # - editing the log file # - capacity to make the pk file, to make the dvi from the generic font, to # view the dvi, to convert dvi to ps from within Alpha # - capacity to make and to edit the property list of a font # - capacity to process an entire folder of mf source files # - ready to use template for a new font # - key bindings to choose the processing mode, process files etc. # - advanced keywords completion # - command clicking on a word leads to its definition # - option clicking on the title bar of a window brings a list of .mf and # .log files at the same level or in a selected folder and allows to edit # them. # # As of this release, both <CMacTeX Metafont> and <OzMetafont> are supported # (together with their respective gftopk, gftodvi, dvipreviewer and tftopl). # # --> Click here on <Metafont Help> to read the instructions or open # this file from the Help menu. # ## Author : Bernard Desgraupes ## e-mail: <berdesg@easynet.fr> ## www: <http://perso.easynet.fr/~berdesg/metafont.html> ## Created : 03/28/99 ## Last modification : 23 juin 2000 - 22:09:55 ## ## Copyright (c) Bernard Desgraupes 1999, 2000 # # ## # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or any # later version : # <http://www.gnu.org/copyleft/gpl.html> # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the FreeSoftware Foundation, # Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ## alpha::mode Mf 1.2.31 mfMenu {*.mf *.plf *.vpl} mfMenu { alpha::package require AlphaTcl 7.2 addMenu mfMenu "Metafont" } maintainer { "Bernard Desgraupes" <berdesg@easynet.fr> <http://perso.easynet.fr/~berdesg/metafont.html> } uninstall this-file help {file "Metafont Help"} namespace eval Mf {} ####### Preferences ############# newPref f wordWrap {0} Mf # Set this flag if you want your source file to be marked automatically when it is opened. newPref f autoMark {1} Mf # Set this flag if you want the tab key to behave electrically (to jump from a bullet # to the next one in templates for instance). newPref f electricTab {1} Mf # Metafont particular processing option. # Metafont particular processing option. newPref f gfcorners 0 Mf Mf::shadowMf # Metafont particular processing option. newPref f imagerules 0 Mf Mf::shadowMf # Metafont particular processing option. newPref f nodisplays 0 Mf Mf::shadowMf # Metafont particular processing option. newPref f notransforms 0 Mf Mf::shadowMf # Metafont particular processing option. newPref f screenstrokes 0 Mf Mf::shadowMf # Metafont particular processing option. newPref f screenchars 0 Mf Mf::shadowMf # Set this flag to build a list of all source files on your installation. # You will have to set the path to the top folder with the PathToSourceFile # preference. Folders can be nested : use the NestingDepth pref to say how deep. newPref f buildSourceFiles 0 Mf Mf::shadowList # If this flag is set all the output will go in the MFworkFolder # instead of going in the same folder as the source file. # This feature works only with CMacTeX Metafont. newPref f useWorkFold 0 Mf # Name of the printer mode for Metafont : for instance cx at 300dpi, # canonex at 600dpi etc. Default is canonex. newPref v mfModeForPrinter canonex Mf # Prefix for comments in Metafont source files. newPref v prefixString {% } Mf # Regular expression used in the Functions pop-up menu # (above the M pop-up menu, top right of the current window). newPref v funcExpr {^(def|vardef|primarydef|secondarydef|tertiarydef) [^\(=@;\r]+} Mf # Metafont mode's notion of what is a word. newPref v wordBreak {[_\w]+} Mf newPref v wordBreakPreface {[^_\w]} Mf # Here we allow the user to customize the denomination of the beginchar macro. newPref v userBeginchar beginchar Mf # To customize the denomination of the endchar macro. newPref v userEndchar endchar Mf # Default colo(u)rs for the keywords newPref v commentColor red Mf newPref v keywordColor blue Mf newPref v stringColor green Mf newPref v primitivesColor magenta Mf # Metafont menu, when used for the first time, must determine # which Metafont application is installed. A proc will do # that automatically, but this choice can be overriden afterwards # in the mode specific prefs. newPref v mfAppSig {} Mf Mf::rebuildOtherfiles # Folder where Metafont sends its output to. newPref folder MfworkFolder $HOME Mf # Where is the file modes.mf defining the parameters' values for # all possible Metafont modes ? newPref file pathToModesMfFile {} Mf # Where is the file plain.mf defining the Metafont's basic macros ? newPref file pathToPlainMfFile {} Mf # Set here the location of a folder containing mf files (for instance the top one on your # installation but not necessarily). It may contain subfolders : choose the depth with # the nestingDepth pref. newPref file pathToSourceFolder {} Mf Mf::shadowList # Choose the depth of subfolders nesting in the main source folder. newPref v nestingDepth {3} Mf Mf::shadowList # To insert your name in the preambule of a new font template. newPref v myName {} Mf # To insert your e-mail in the preambule of a new font template. newPref v myEMail {} Mf # To insert your home page in the preambule of a new font template. newPref url myWebPage {http://} Mf ####### Initialization of some variables ############# set MFtailfilename [file tail [win::Current]] set chosenMode proof set mag 1 set vars [list gfcorners imagerules nodisplays notransforms screenchars screenstrokes \ magstep magflag magstepflag Mfbasefileflag mfset] foreach v $vars { set $v 0 } set vars [list prefixtfm prefixplf prefixgf prefixdvi prefixlog prefixrmall fromfolder] foreach v $vars { set $v "(" } set mfwd $HOME set MFoutputfolder $MfmodeVars(MfworkFolder) set Mfbasefile "" set tfmfile "" set MFcurrentdir "" set MFfilenames "" # To prefix subfolders names in the Source Files menu: set mfsymb "•" set Mf::commentCharacters(General) "%" set Mf::commentCharacters(Paragraph) [list "%% " " %%" " % "] set Mf::commentCharacters(Box) [list "%" 1 "%" 1 "%" 3] proc mfMenu {} {} hook::register activateHook Mf::rebuildOtherfiles Mf ############# Select the Metafont application when using this mode for the first time ############# if {$MfmodeVars(mfAppSig)== ""} { set mfsignlist [list "CMacTex mf" "OzMetafont"] set sig [listpick -p "Select your Metafont application" $mfsignlist] switch $sig { "CMacTex mf" {set mfAppSig "CMT3"} "OzMetafont" {set mfAppSig "OzMF"} } removeArrDef MfmodeVars mfAppSig set MfmodeVars(mfAppSig) $mfAppSig addArrDef MfmodeVars mfAppSig $mfAppSig } # # A proc to search a directory 'dir' and all its subdirectories looking for files # # with extension 'mf'. proc Mf::listSrcInDir {dir ext} { global MFfilenames set itemslist($dir) [glob -nocomplain -dir $dir *] foreach f $itemslist($dir) { if {[file isfile $f] && [file extension [file tail $f]]==".mf"} { set f [file tail $f] regsub "\(\[^\\.\]\)\.mf" $f "\\1" f lappend MFfilenames " $f" } elseif {[file isdirectory $f]} { Mf::listSrcInDir $f mf } } } ############################################## # # # Metafont Menus Building Procs # # # ############################################## menu::buildProc mfMenu menu::buildMf menu::buildProc otherFiles menu::buildotherFiles menu::buildProc removeFiles menu::buildremoveFiles menu::buildProc sourceFiles menu::buildsourceFiles proc menu::buildMf {} { global mfMenu otherFiles MFtailfilename set ma { "switchToMetafont" "(-" "/R<UrunTheBuffer" "saveAndRun" "<E<SrunAFile" "<S<IrunAFolder" "<S<BrunCurrentFolder" "(-" {Menu -n "metafontMode" -p Mf::choosemodeProc { "proof" "smoke" "localfont" "userDefined" } } {Menu -n "processingOptions" -p Mf::processingoptProc { "mag..." "magstep..." "baseFile..." "(-" "gfcorners" "imagerules" "nodisplays" "notransforms" "screenchars" "screenstrokes" "(-" "clearAllOptions" } } "(-" } lappend ma [list Menu -n sourceFiles {}] lappend ma [list Menu -n otherFiles {}] append ma { "(-" "newFontTemplate" "(-" {Menu -n "variables" -p Mf::variablesProc { " boolean" " numeric" " pair" " path" " pen" " picture" " string" " transform" " newinternal" } } {Menu -n "boolean" -p Mf::booleanProc { " charexists" " cycle" " false" " known" " true" " unknown" } } {Menu -n "functions" -p Mf::functionsProc { " angle" " ceilling" " floor" " cosd" " sind" " mexp" " mlog" " sqrt" "(-" " round" " hround" " vround" " dotprod" "(-" " eps" " epsilon" " infinity" "(-" " solve" " tolerance" "(-" " normaldeviate" " randomseed" " uniformdeviate" " whatever" } } {Menu -n "positioning" -p Mf::positioningProc { " direction" " directionpoint" " directiontime" " penoffset" " point…of" " precontrol…of" " postcontrol…of" " intersectionpoint" " intersectiontimes" "(-" " good.bot" " good.lft" " good.rt" " good.top" " good.x" " good.y" "(-" " xpart" " xxpart" " xypart" " ypart" " yxpart" " yypart" " clearxy" } } {Menu -n "paths" -p Mf::pathsProc { " penstroke" " build…penstroke" "(-" " flex" " fullcircle" " halfcircle" " quartercircle" " superellipse" " unitsquare" "(-" " makepath" " interpath" " subpath" " tensepath" " counterclockwise" " reverse" "(-" " turningnumber" } } {Menu -n "pens" -p Mf::pensProc { " <E<Spencircle" " <S<Opickup…pencircle" " <S<Ipencircle…scaled" " <S<I<Opickup…pencircle…scaled" " <E<Spensquare" " <S<Opickup…pensquare" " <S<Ipensquare…scaled" " <S<I<Opickup…pensquare…scaled" " penrazor" " penspeck" "(-" " penpos" "(-" " clear_pen_memory" " clearpen" " currentpen" " makepen" " nullpen" " savepen" "(-" " pen_bot" " pen_lft" " pen_rt" " pen_top" " pickup" } } {Menu -n "pictures" -p Mf::picturesProc { " blankpicture" " clearit" " currentpicture" " nullpicture" "(-" " totalweight" " unitpixel" } } {Menu -n "transformations" -p Mf::transformationsProc { " currenttransform" " identity" " inverse" " reflectedabout" " rotated" " rotatedaround" " scaled" " shifted" " slanted" " transformed" " xscaled" " yscaled" " zscaled" } } {Menu -n "definitions" -p Mf::definitionsProc { " def…enddef" " suffix" " expr" " text" " primarydef…enddef" " secondarydef…enddef" " tertiarydef…enddef" " vardef…enddef" " begingroup…endgroup" } } {Menu -n "conditions" -p Mf::conditionsProc { " for…endfor" " forever…endfor" " forsuffixes…endfor" " if…fi" " if…elseif…else…fi" " downto" " upto" " step…until" " exitif" " exitunless" } } {Menu -n "drawing" -p Mf::drawingProc { " <Saddto…also" " <S<Iaddto…currentpicture" " <E<Saddto…contour" " <S<Iaddto…contour…withpen" " <S<Oaddto…contour…withweight" " <E<Saddto…doublepath" " <S<Iaddto…doublepath…withpen" " <S<Oaddto…doublepath…withweight" " <E<Scull…dropping" " <S<Ocull…dropping…withweight" " <E<Scull…keeping" " <S<Ocull…keeping…withweight" " cullit" "(-" " <E<Sdraw" " <S<Iundraw" " <E<Sdrawdot" " <S<Iundrawdot" " <E<Sfill" " <S<Iunfill" " <E<Sfilldraw" " <S<Iunfilldraw" "(-" " cutdraw" " cutoff" " erase" } } {Menu -n "characters" -p Mf::charactersProc { " beginchar…endchar" " extra_beginchar" " extra_endchar" } } {Menu -n "modesDefinitions" -p Mf::unitsProc { " blacker" " fillin" " o_correction" " fix_units" " mode_setup" " pixels_per_inchs" " aspect_ratio" } } {Menu -n "pixellisation" -p Mf::pixellisationProc { " define_pixels" " define_blacker_pixels" " define_good_x_pixels" " define_good_y_pixels" " define_corrected_pixels" " define_horizontal_corrected_pixels" " define_whole_pixels" " define_whole_blacker_pixels" " define_whole_vertical_pixels" " define_whole_vertical_blacker_pixels" } } {Menu -n "fontInternals" -p Mf::fontInternalsProc { " charlist" " extensible" " font_coding_scheme" " font_extra_space" " font_identifier" " font_normal_shrink" " font_normal_space" " font_normal_stretch" " font_quad" " font_size" " font_slant" " font_x_height" " fontdimen" " headerbytes" " ligtable" " kern" } } {Menu -n "strings" -p Mf::stringsProc { " ditto" " jobname" " readstring" " substring" } } {Menu -n "displaying" -p Mf::displayingProc { " currentwindow" " display…inwindow" " openwindow…from…to…at" " screen_cols" " screen_rows" " screenrule" } } {Menu -n "output" -p Mf::outputProc { " openit" " shipit" " showit" "(-" " labels" " labels…range…thru" " penlabels" " makelabel" " makegrid..." "(-" " proofoffset" " proofrule" " proofrulethickness" "(-" " grayfont" " labelfont" " slantfont" " titlefont" } } {Menu -n "debugging" -p Mf::debuggingProc { " errhelp" " errmessage" " message" " stop" "(-" " show" " showdependencies" " showstats" " showtoken" " showvariable" "(-" " loggingall" " tracingall" " tracingnone" "(-" " batchmode" " errorstopmode" " nonstopmode" " scrollmode" } } {Menu -n "misc" -p Mf::miscProc { " capsule_def" " expandafter" " gobble" " gobbled" " interact" " numtok" " scantokens" " special" " numspecial" } } {Menu -n "internalVariables" -p Mf::varintProc { " autorounding" " designsize" " fontmaking" " granularity" " pausing" " proofing" " showstopping" " smoothing" "(-" " charcode" " chardp" " chardx" " chardy" " charext" " charht" " charic" " charwd" "(-" " hppp" " vppp" "(-" " xoffset" " yoffset" "(-" " day" " month" " year" " time" "(-" " tracingcapsules" " tracingchoices" " tracingcommands" " tracingedges" " tracingequations" " tracingmacros" " tracingonline" " tracingoutput" " tracingpens" " tracingrestores" " tracingspecs" " tracingstats" " tracingtitles" " turningcheck" " warningcheck" } } } return [list build $ma Mf::menuProc {sourceFiles otherFiles} $mfMenu] } proc menu::buildotherFiles {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars mfAppSig MfworkFolder fromfolder MFcurrentdir global prefixtfm prefixdvi prefixplf prefixgf prefixlog prefixrmall set MFbasefilename [file rootname [file tail [win::Current]]] set ma "${prefixgf}convertGfToPk" if {$MfmodeVars(mfAppSig) == "CMT3"} { lappend ma "<E${prefixgf}convertGfToDvi" } lappend ma "<E${prefixdvi}view $MFbasefilename.dvi" if {$MfmodeVars(mfAppSig) == "CMT3"} { lappend ma "<E${prefixdvi}convert $MFbasefilename.dvi to ps" } lappend ma "<E<S${prefixtfm}convert $MFbasefilename.tfm to pl" lappend ma "<E<StfmToPl..." lappend ma "<S<ItfmToPlAFolder..." lappend ma "<S<BtfmToPlCurrentFolder" lappend ma "<E<SvpToVf..." lappend ma "<S<IvpToVfAFolder..." lappend ma "<S<BvpToVfCurrentFolder" lappend ma "(-" lappend ma "<S${prefixlog}open $MFbasefilename.log" lappend ma "<S<I${fromfolder}openAllLogFiles" lappend ma "<E<S${prefixplf}openPropertyList" lappend ma "<S<I${fromfolder}openAllPropertyLists" foreach i {"(-" "open modes.mf" "open plain.mf" "(-" "metafontBindings"} { lappend ma $i } lappend ma "chooseAFolder..." lappend ma [list Menu -n removeFiles {}] lappend ma "(-" if {$MFcurrentdir != ""} { lappend ma [menu::itemWithIcon "currentFolderIs:" 83] lappend ma " [file tail $MFcurrentdir]" } else { lappend ma [menu::itemWithIcon "noFolderSelected" 82] } return [list build $ma Mf::otherfilesProc {removeFiles} ] } proc menu::buildremoveFiles {} { global MFcurrentdir prefixrmall set ma "${prefixrmall}allLogFiles" lappend ma "${prefixrmall}allGfFiles" lappend ma "${prefixrmall}allPkFiles" lappend ma "${prefixrmall}allDviFiles" lappend ma "${prefixrmall}allTfmFiles" lappend ma "${prefixrmall}allVfFiles" lappend ma "${prefixrmall}allPlFiles" lappend ma "${prefixrmall}allVplFiles" lappend ma "(-" lappend ma "${prefixrmall}allOfThem" return [list build $ma Mf::removefilesProc ] } proc menu::buildsourceFiles {} { global mfSubmenuItems MfmodeVars pathToSourceFolder buildSourceFiles global nestingDepth MFfilenames reste mfsymb set defaultSubmenuItems "Menu -m -n sourceFiles -p Mf::sourceFilesProc \{{Rebuild Source List} {(-}\}" if {$MfmodeVars(buildSourceFiles)} { if {$MfmodeVars(pathToSourceFolder) == ""} { catch {get_directory -p "Locate the mf sources folder."} mfdir if {$mfdir != ""} { removeArrDef MfmodeVars pathToSourceFolder set MfmodeVars(pathToSourceFolder) $mfdir addArrDef MfmodeVars pathToSourceFolder $mfdir } else { set MFfilenames {} return $defaultSubmenuItems } } if { ![info exists mfSubmenuItems] || $mfSubmenuItems == "" } { global mfPaths set reste "" set mfSubmenuItems \ [menu::buildHierarchy $MfmodeVars(pathToSourceFolder) "sourceFiles" \ Mf::sourceFilesProc mfPaths ".mf" $MfmodeVars(nestingDepth)] regexp {^Menu -m -n sourceFiles -p Mf::sourceFilesProc \{(.*)$} $mfSubmenuItems "" reste regsub -all "(Menu -m -n\[ \]+(\{)?)" $reste "\\1$mfsymb" reste set mfSubmenuItems "Menu -m -n sourceFiles -p Mf::sourceFilesProc \{{Rebuild Source List} {(-} $reste" } } else { set mfSubmenuItems $defaultSubmenuItems } if {$MfmodeVars(pathToSourceFolder) == ""} { Mf::listSrcInDir [file dirname [win::Current]] mf } else { Mf::listSrcInDir $MfmodeVars(pathToSourceFolder) mf } return $mfSubmenuItems } menu::buildSome mfMenu markMenuItem metafontMode proof 1 ################################################################ # Main Menus and Submenus procs # ################################################################ proc Mf::menuProc {menu item} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars useWorkFold MfworkFolder global cmdline name switch $item { "switchToMetafont" {app::launchFore $MfmodeVars(mfAppSig)} "runTheBuffer" { Mf::setnames [win::Current] Mf::checkdirty Mf::runbufferProc} "saveAndRun" { save Mf::setnames [win::Current] Mf::runbufferProc } "runAFile" { catch {getfile "Select a \".mf\" file to process"} name Mf::setnames $name edit $MFfullfilename if {[file exists $MFfullfilename]} { Mf::runbufferProc } } "runAFolder" {Mf::runafolderProc} "runCurrentFolder" {Mf::runcurrfoldProc} "newFontTemplate" {Mf::newtemplateProc} } } proc Mf::otherfilesProc {submenu item} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars MfworkFolder mfAppSig gffile MFcurrentdir global Mffolderpath tfmfile vplfile mfwd global prefixplf prefixdvi prefixrmall global tileLeft tileTop tileWidth errorHeight fromfolder switch -regexp $item { "openplain.mf" {Mf::openplainmfProc} "openmodes.mf" {Mf::openmodesmfProc} "convertGfToPk" { Mf::setnames [win::Current] Mf::findgfFile Mf::dopkProc } "convertGfToDvi" { Mf::setnames [win::Current] Mf::findgfFile Mf::dodviProc set prefixdvi "" menu::buildSome otherFiles } "convert.*\.dvi" { Mf::setnames [win::Current] Mf::dviToPsProc } "view.*\.dvi" { Mf::setnames [win::Current] Mf::viewdviProc } "convert.*\.tfm" { Mf::setnames [win::Current] Mf::doplProc set prefixplf "" menu::buildSome otherFiles Mf::editplProc } "tfmToPlAFolder..." {Mf::tftoplafolderProc} "tfmToPlCurrentFolder" {Mf::tftoplcurrfoldProc} "tfmToPl..." { catch {getfile "Select a tfm file"} tfmfile if {$tfmfile == ""} { return } else { Mf::setnames $tfmfile Mf::doplProc edit -r [file join $MFdirfilename $MFbasefilename.plf] } } "vpToVfAFolder..." {Mf::vptovfafolderProc} "vpToVfCurrentFolder" {Mf::vptovfcurrfoldProc} "vpToVf..." { catch {getfile "Select a vpl file"} vplfile if {$vplfile == ""} { return } else { edit -r "$vplfile" Mf::setnames $vplfile Mf::dovplProc } } "open.*\.log$" { Mf::setnames [win::Current] Mf::editlogProc } "openPropertyList" { Mf::setnames [win::Current] Mf::editplProc } "openAllLogFiles" {Mf::allAuxfilesProc log} "openAllPropertyLists" { Mf::allAuxfilesProc plf Mf::allAuxfilesProc pl } "chooseAFolder..." { catch {get_directory -p "Select a folder."} MFcurrentdir if {$MFcurrentdir == ""} { return } set prefixrmall "" set fromfolder "" set Mffolderpath $MFcurrentdir menu::buildSome otherFiles } "currentFolderIs:" { alertnote "Current folder is: $MFcurrentdir" } "metafontBindings" { set mess "KEY BINDINGS AVAILABLE IN METAFONT MODE\n\n" append mess "Press 'ctrl-m', release, then hit one of the following letters :\n" append mess " 'b' to process the <b>uffer\n" append mess " 'c' to edit the macro <c>ommands file 'plain.mf'\n" append mess " 'd' to process a <d>irectory\n" append mess " 'f' to process a <f>ile\n" append mess " 'g' to edit the lo<g> file\n" append mess " 'i' to convert gf file to dv<i>\n" append mess " 'k' to convert gf file to p<k>\n" append mess " 'l' to select <l>ocalfont mode\n" append mess " 'm' to edit the <m>odes file 'modes.mf'\n" append mess " 'n' to create a <n>ew font template\n" append mess " 'p' to select <p>roof mode\n" append mess " 's' to select <s>moke mode\n" append mess " 't' to convert <t>fm file to pl\n" append mess " 'u' to select <u>ser defined mode\n" append mess " 'v' to <v>iew the d<v>i\n" new -g $tileLeft $tileTop $tileWidth [expr $errorHeight + 60] -n "* Metafont Bindings *" -info $mess set start [minPos] while {![catch {search -f 1 -s -r 1 {('|<)[a-z-]+('|>)} $start} res]} { insertColorEscape [lindex $res 0] 1 insertColorEscape [lindex $res 1] 0 set start [lindex $res 1] } insertColorEscape 0 5 insertColorEscape [nextLineStart 0] 0 refresh } } } # Here is a proc to dimm/undimm the items of the OtherFiles submenu # depending on the existence of auxiliary files proc Mf::rebuildOtherfiles {name} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global mfMenu otherFiles global MfmodeVars MfworkFolder mfAppSig global prefixgf prefixdvi prefixlog prefixtfm prefixplf Mf::setnames [win::Current] if {![regexp ".mf" $MFtailfilename] && ![regexp ".plf" $MFtailfilename]} { set prefixgf "(" set prefixdvi "(" set prefixlog "(" set prefixtfm "(" set prefixplf "(" } else { if {[file exists [file join $MFoutputfolder $MFbasefilename.log]]} { set prefixgf "" set prefixlog "" } else { set prefixgf "(" set prefixlog "(" } if {[file exists [file join $MFoutputfolder $MFbasefilename.dvi]]} { set prefixdvi "" } else { set prefixdvi "(" } if {[file exists [file join $MFoutputfolder $MFbasefilename.tfm]]} { set prefixtfm "" } else { set prefixtfm "(" } if {[file exists [file join $MFoutputfolder $MFbasefilename.plf]] \ || [file exists [file join $MFoutputfolder $MFbasefilename.pl]]} { set prefixplf "" } else { set prefixplf "(" } } menu::buildSome otherFiles } # Choosing Metafont printer mode proc Mf::choosemodeProc {menu item} { global MfmodeVars mfModeForPrinter chosenMode global proof smoke localfont userDefined switch $item { "proof" { set chosenMode proof Mf::choosemodeMark proof Mf::dimmOtherfiles message "mode proof - no tfm produced" } "smoke" { set chosenMode smoke Mf::choosemodeMark smoke Mf::dimmOtherfiles message "mode smoke - no tfm produced" } "localfont" { set chosenMode localfont Mf::choosemodeMark localfont Mf::undimmOtherfiles message "mode localfont" } "userDefined" { set chosenMode $MfmodeVars(mfModeForPrinter) Mf::choosemodeMark userDefined Mf::undimmOtherfiles message "mode \"$MfmodeVars(mfModeForPrinter)\"" alertnote "Current user defined mode is \"$MfmodeVars(mfModeForPrinter)\". You can change this in the Current Mode Prefs." } } } proc Mf::choosemodeMark {var} { Mf::clearAllModes markMenuItem metafontMode $var 1 } proc Mf::clearAllModes {} { global proof smoke localfont userDefined foreach i {"proof" "smoke" "localfont" "userDefined"} { markMenuItem metafontMode $i 0 } } # Choosing Metafont processing Options proc Mf::processingoptProc {menu item} { global mag magstep magflag magstepflag Mfbasefileflag global MfmodeVars Mfbasefile switch $item { "mag..." { catch {prompt "Choose a magnification" $mag} res if {$res == "cancel"} {return} if {$res == 1} { set magflag 0 set mag $res markMenuItem processingOptions "mag..." $magflag } else { set magstep 0 set magstepflag 0 set magflag 1 set mag $res markMenuItem processingOptions "mag..." $magflag markMenuItem processingOptions "magstep..." $magstepflag } } "magstep..." { catch {prompt "Choose a magstep coefficient " $magstep} res if {$res == "cancel"} {return} if {$res == 0} { set magstepflag 0 set magstep $res markMenuItem processingOptions "magstep..." $magstepflag } else { set mag 1 set magflag 0 set magstepflag 1 set magstep $res markMenuItem processingOptions "mag..." $magflag markMenuItem processingOptions "magstep..." $magstepflag } } "baseFile..." { catch {getfile "Select a base file"} Mfbasefilepath set Mfbasefile [file tail $Mfbasefilepath] set Mfbasefileflag 1 markMenuItem processingOptions "baseFile..." $Mfbasefileflag } "gfcorners" {Mf::Toggle gfcorners} "imagerules" {Mf::Toggle imagerules} "nodisplays" {Mf::Toggle nodisplays} "notransforms" {Mf::Toggle notransforms} "screenchars" {Mf::Toggle screenchars} "screenstrokes" {Mf::Toggle screenstrokes} "clearAllOptions" {Mf::clearAllOptionsProc} } } proc Mf::Toggle {var} { global $var set $var [expr {[set $var] ? 0 : 1}] synchroniseModeVar $var Mf::shadowMf $var } proc Mf::shadowMf {name} { global gfcorners imagerules nodisplays global notransforms screenchars screenstrokes switch $name { "gfcorners" { markMenuItem processingOptions gfcorners $gfcorners } "imagerules" { markMenuItem processingOptions imagerules $imagerules } "nodisplays" { markMenuItem processingOptions nodisplays $nodisplays } "notransforms" { markMenuItem processingOptions notransforms $notransforms } "screenchars" { markMenuItem processingOptions screenchars $screenchars } "screenstrokes" { markMenuItem processingOptions screenstrokes $screenstrokes } } } proc Mf::shadowList {name} { global SourceFiles MfmodeVars pathToSourceFolder buildSourceFiles mfSubmenuItems nestingDepth set mfSubmenuItems "" menu::buildSome sourceFiles } proc Mf::clearAllOptionsProc {} { global gfcorners imagerules nodisplays global notransforms screenchars screenstrokes global mag magflag magstep magstepflag Mfbasefile Mfbasefileflag foreach i {"gfcorners" "imagerules" "nodisplays" "notransforms" "screenchars" "screenstrokes"} { set $i 0 Mf::shadowMf $i } set mag 1 set magflag 0 set magstep 0 set magstepflag 0 set Mfbasefileflag 0 set Mfbasefile "" markMenuItem processingOptions "baseFile..." $Mfbasefileflag markMenuItem processingOptions "mag..." $magflag markMenuItem processingOptions "magstep..." $magstepflag } proc Mf::dimmOtherfiles {} { enableMenuItem otherFiles "convertTfmToPl" 0 enableMenuItem otherFiles "openPropertyList" 0 } proc Mf::undimmOtherfiles {} { enableMenuItem otherFiles "convertTfmToPl" 1 enableMenuItem otherFiles "openPropertyList" 1 } proc Mf::removefilesProc {menu item} { global MfmodeVars mfAppSig MFcurrentdir prefixrmall fromfolder Mffolderpath switch $item { "allLogFiles" {Mf::deleteallfilesProc log} "allGfFiles" {Mf::deleteallfilesProc gf} "allPkFiles" {Mf::deleteallfilesProc pk} "allDviFiles" {Mf::deleteallfilesProc dvi} "allTfmFiles" {Mf::deleteallfilesProc tfm} "allVfFiles" {Mf::deleteallfilesProc vf} "allPlFiles" {Mf::deleteallfilesProc plf} "allVplFiles" {Mf::deleteallfilesProc vpl} "allOfThem" { foreach ext {"log" "gf" "pk" "dvi" "tfm" "vf" "plf" "vpl"} { Mf::deleteallfilesProc $ext } } } Mf::rebuildOtherfiles "" } ################################################## # # # Procs to process the Metafont source files # # # ################################################## proc Mf::runbufferProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global cmdline addcmdline MfmodeVars mfAppSig global chosenMode resol if {[string length $MfmodeVars(mfAppSig)]} { app::launchFore "$MfmodeVars(mfAppSig)" switch $MfmodeVars(mfAppSig) { "CMT3" { Mf::buildCMTcmdLine Mf::doMfscript } "OzMF" { if {$chosenMode == "proof"} { Mf::doMfscript Mf::updateprefixes } else { set resol "[Mf::findmoderes]" Mf::buildOZmakeLine Mf::createmakefile Mf::runmakefile Mf::updateprefixes } } } menu::buildSome otherFiles } else { alertnote "No Mf app. selected. Select it in the Current mode preferences." } } proc Mf::runafolderProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global cmdline MfmodeVars mfAppSig MFcurrentdir global chosenMode resol prefixrmall global filesindir ext MfworkFolder Mffolderpath fromfolder catch {get_directory -p "Select a folder."} Mffolderpath set MFcurrentdir $Mffolderpath if {$Mffolderpath == ""} { return } set prefixrmall "" set ext ".mf" set filesindir [glob -nocomplain -dir [file join $Mffolderpath] *$ext] if {[llength $filesindir] == 0} { alertnote "No \"$ext\" file in this folder." return } if {[string length $MfmodeVars(mfAppSig)]} { switch $MfmodeVars(mfAppSig) { "CMT3" {Mf::domaketexpk} "OzMF" {Mf::domaketexpk} } set fromfolder "" menu::buildSome otherFiles } else { alertnote "No Mf app. selected. Select it in the Current mode preferences." } } proc Mf::runcurrfoldProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global cmdline MfmodeVars mfAppSig MFcurrentdir global chosenMode resol prefixrmall global filesindir ext MfworkFolder Mffolderpath fromfolder if {$MFcurrentdir == ""} { alertnote "No folder currently selected" return } set prefixrmall "" set ext ".mf" set Mffolderpath: $MFcurrentdir set filesindir [glob -nocomplain -dir [file join $Mffolderpath] *$ext] if {[llength $filesindir] == 0} { alertnote "No \"$ext\" file in this folder." return } if {[string length $MfmodeVars(mfAppSig)]} { switch $MfmodeVars(mfAppSig) { "CMT3" {Mf::domaketexpk} "OzMF" {Mf::domaketexpk} } set fromfolder "" menu::buildSome otherFiles } else { alertnote "No Mf app. selected. Select it in the Current mode preferences." } } proc Mf::domaketexpk {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global cmdline MfmodeVars mfAppSig global chosenMode resol global filesindir ext MfworkFolder Mffolderpath fromfolder if {[file exists [file join $Mffolderpath tmpall.make]]} { file delete [file join $Mffolderpath tmpall.make] } switch [buttonAlert "OK to process all \"$ext\" files from $Mffolderpath ?" "yes" "cancel" ] { "yes" { set fileId [open [file join $Mffolderpath tmpall.make] a+] set resol "[Mf::findmoderes]" message "$resol" foreach file $filesindir { # We open each file because in the case when no mf file is open # we get problems with unrecognized MfmodeVars values edit -w $file set MFfullfilename $file set MFtailfilename [file tail $file] Mf::buildOZmakeLine # message "$cmdline" puts $fileId $cmdline } close $fileId Mf::runmakeallfile } "cancel" { app::launchFore "ALFA" return } } } proc Mf::checkdirty {} { if {[winDirty]} { case [askyesno -c "Dirty window '[lindex [winNames] 0]'. Do you want to save it ?"] in { "yes" {save} "no" {} "cancel" {return} } } } ################################# # # # Scripts and Command Lines # # # ################################# proc Mf::buildCMTcmdLine {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global cmdline MfmodeVars chosenMode mfModeForPrinter MfworkFolder useWorkFold global proof smoke localfont userDefined script global gfcorners imagerules nodisplays global notransforms screenchars screenstrokes global mag magstep magflag magstepflag Mfbasefile Mfbasefileflag set cmdline "mf " # choosing the mode if {$chosenMode != "proof"} { if {$chosenMode == "smoke" || $chosenMode == "localfont"} { append cmdline "\\mode=$chosenMode; " } else { append cmdline "\\mode=$MfmodeVars(mfModeForPrinter);" } } else { append cmdline "\\ " } # Do we magnify ? if {$magflag == 1} { append cmdline "mag=$mag; " } elseif {$magstepflag == 1} { append cmdline "mag=magstep\($magstep\); " } # Add the (optional!) options if the corresponding flag is set if {$screenchars} {append cmdline "screenchars; "} if {$screenstrokes} { if {$chosenMode != "proof"} { alertnote "The \"screenstrokes\" option is for proof mode only. I'll ignore it." Mf::Toggle screenstrokes Mf::shadowMf screenstrokes } else { append cmdline "screenstrokes; " } } if {$imagerules} { append cmdline "imagerules; " } if {$gfcorners} { append cmdline "gfcorners; " } if {$nodisplays} { if {$chosenMode != "proof"} { alertnote "The \"nodisplays\" option is for proof mode only. I'll ignore it." } elseif {$screenchars || $screenstrokes} { beep alertnote "Contradictory options : you can't use \"nodisplays\" with \"screenchars\" or \"screenstrokes\". I'll ignore it." Mf::Toggle nodisplays Mf::shadowMf nodisplays } else { append cmdline "nodisplays; " } } if {$notransforms} { append cmdline "notransforms; " } # Input a base file if any if {$Mfbasefileflag == 1} { append cmdline "input $Mfbasefile;" } append cmdline "input $MFtailfilename;" # Now the file to process. Since version 2.2.1 of CMaCTeX Metafont there is a new syntax # for the Apple event : the destination folder is included in the script line # and introduced by -@ # if {[lindex [Mf::getMfVersion] 1] > 2.2} { # append cmdline " -@ [set MFoutputfolder]:" # } set cmdline [curlyq $cmdline] # Finally we update prefixes to rebuild accordingly the Other Files submenu Mf::updateprefixes } # OzMetafont cannot receive a complete command line through an Apple Event. # The workaround is to create a ".make" file which OzMetafont will process # with its built-in MakeTeXPK. # (Good) side effect : the "pk" files will be done in the same time, # thus no need to invoke gftopk after that. proc Mf::buildOZmakeLine {} { global cmdline MFfullfilename MFtailfilename MfmodeVars chosenMode global proof smoke localfont userDefined script resol mfModeForPrinter global gfcorners imagerules nodisplays global notransforms screenchars screenstrokes global mag magstep magflag magstepflag Mfbasefile Mfbasefileflag set cmdline "MakeTeXPK [file rootname $MFtailfilename] " # What is the resolution corresponding to the printer mode ? We look for it in the # modes.mf file. append cmdline "[lindex $resol 1] [lindex $resol 1] " # Do we magnify ? if {$magflag == 1} { append cmdline "$mag " } elseif {$magstepflag == 1} { append cmdline "magstep\($magstep\) " } else { append cmdline "1 " } # Choose the mode if {$chosenMode == "localfont"} { append cmdline "[lindex $resol 0]" } elseif {$chosenMode == "proof" || $chosenMode == "smoke"} { append cmdline "$chosenMode" } else { append cmdline $MfmodeVars(mfModeForPrinter) } # Add the (optional!) options if the corresponding flag is set if {$screenchars} {append cmdline ";screenchars"} if {$screenstrokes} { if {$chosenMode != "proof"} { alertnote "The \"screenstrokes\" option is for proof mode only. I'll ignore it." Mf::Toggle screenstrokes Mf::shadowMf screenstrokes } else { append cmdline ";screenstrokes" } } if {$imagerules} { append cmdline ";imagerules" } if {$gfcorners} { append cmdline ";gfcorners" } if {$nodisplays} { if {$chosenMode != "proof"} { alertnote "The \"nodisplays\" option is for proof mode only. I'll ignore it." } elseif {$screenchars || $screenstrokes} { beep alertnote "Contradictory options : you can't use \"nodisplays\" with \"screenchars\" or \"screenstrokes\". I'll ignore it." Mf::Toggle nodisplays Mf::shadowMf nodisplays } else { append cmdline ";nodisplays" } } if {$notransforms} { append cmdline ";notransforms" } # Input a base file if any if {$Mfbasefileflag == 1} { append cmdline ";input $Mfbasefile" } # Finally we update prefixes to rebuild the "Other Files" submenu Mf::updateprefixes } proc Mf::doMfscript {} { global cmdline MFfullfilename MFoutputfolder global MfmodeVars mfAppSig switch $MfmodeVars(mfAppSig) { "CMT3" { set name [file join $MFoutputfolder ""] eval "AEBuild -t 6000 'CMT3'" CMTX exec {----} [list $cmdline] dest [tclAE::build::alis $name] } "OzMF" { app::launchFore "OzMF" dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f $MFfullfilename } } } proc Mf::createmakefile {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global cmdline set fileId [open "[file dirname $MFfullfilename]:tmp.make" w+] puts $fileId $cmdline close $fileId } proc Mf::runmakefile {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # app::launchFore "OzMF" dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f [file join $MFdirfilename tmp.make] } proc Mf::runmakeallfile {} { global Mffolderpath MfmodeVars mfAppSig switch $MfmodeVars(mfAppSig) { "CMT3" { app::launchFore "CMT9" dosc -c 'CMT9' -k 'aevt' -e 'odoc' -t 600 -r -f [file join $Mffolderpath tmpall.make] } "OzMF" { app::launchFore "OzMF" dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f [file join $Mffolderpath tmpall.make] } } } proc Mf::updateprefixes {} { global prefixtfm prefixdvi prefixplf prefixgf prefixlog chosenMode if {$chosenMode == "proof" || $chosenMode == "smoke"} { set prefixtfm "(" } else { set prefixtfm "" } set prefixplf "(" set prefixdvi "(" set prefixgf "" set prefixlog "" } ######################################### # # # Procs to run the related programs # # # ######################################### # This proc calls up gftopk proc Mf::dopkProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global gffile MfmodeVars MfworkFolder mfAppSig mfset global mfwd Mffolderpath switch $MfmodeVars(mfAppSig) { "CMT3" { if {![file exists [file join $MFoutputfolder $gffile]]} { alertnote "Can't find file $gffile." return } set pkcmdline "gftopk [file join $MFoutputfolder $gffile]" app::launchFore "CMTe" set pkcmdline [curlyq $pkcmdline] eval "AEBuild 'CMTe'" CMTX exec {----} [list $pkcmdline] } "OzMF" { if {![file exists [file join $mfwd $gffile]]} { alertnote "Can't find file $gffile. Check that the \"delete_gf\" flag in OzMetafont configs is set to false." return } app::launchFore "OzMF" dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 6000 -r -f [file join $mfwd $gffile] } } } # This proc calls up gftodvi proc Mf::dodviProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global gffile MfmodeVars MfworkFolder mfAppSig mfset global mfwd Mffolderpath MFoutputfolder switch $MfmodeVars(mfAppSig) { "CMT3" { if {![file exists [file join $MFoutputfolder $gffile]]} { alertnote "Can't find file $gffile." return } if {[app::isRunning CMTd]} { sendQuitEvent 'CMTd' alertnote "Click to convert [file tail $gffile] to dvi." } set dvicmdline "gftodvi [file join $MFoutputfolder $gffile]" app::launchFore "CMTd" set dvicmdline [curlyq $dvicmdline] eval "AEBuild 'CMTd'" CMTX exec {----} [list $dvicmdline] } "OzMF" { if {![file exists [file join $mfwd $gffile]]} { alertnote "Can't find file $gffile. Check that the \"delete_gf\" flag in OzMetafont configs is set to false." return } app::launchFore "OzMF" dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 6000 -r -f [file join $mfwd $gffile] } } } # This proc calls up a previewer to view the dvi file produced by gftodvi. # For CMaCTeX, it looks in the output folder, then sends the Apple Event to dvipreview : # note : if you prefer xdvi, change the signature from PIVD to CMT8) # for Oz, it looks in the current window's folder then sends the event to OzTeX. proc Mf::viewdviProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global gffile MfmodeVars MfworkFolder mfAppSig mfset global mfwd Mffolderpath rootname switch $MfmodeVars(mfAppSig) { "CMT3" { if {![file exists [file join $MFoutputfolder $MFbasefilename.dvi]]} { alertnote "Can't find file $MFbasefilename.dvi." return } app::launchFore "PIVD" # app::launchElseTryThese "PIVD" "CMT8" dosc -c 'PIVD' -k 'aevt' -e 'odoc' -r -f [file join $MFoutputfolder $MFbasefilename.dvi] } "OzMF" { if {![file exists [file join $MFdirfilename $MFbasefilename.dvi]]} { alertnote "Can't find file $MFbasefilename.dvi." return } app::launchFore "OTEX" dosc -c 'OTEX' -k 'aevt' -e 'odoc' -t 600 -r -f [file join $MFdirfilename $MFbasefilename.dvi] } } } # This proc calls up CMacTeX dvips proc Mf::dviToPsProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # if {![file exists [file join $MFoutputfolder $MFbasefilename.dvi]]} { alertnote "Can't find file $MFbasefilename.dvi." return } app::launchFore "CMT1" dosc -c 'CMT1' -k 'aevt' -e 'odoc' -r -f [file join $MFoutputfolder $MFbasefilename.dvi] } # This proc calls up tftopl proc Mf::doplProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global rootname MfmodeVars MfworkFolder mfAppSig tfmfile mfset global mfwd Mffolderpath MFoutputfolder switch $MfmodeVars(mfAppSig) { "CMT3" { if {[app::isRunning CMTk]} { sendQuitEvent 'CMTk' alertnote "Click to proceed." } if {$mfset} { set mfwd $Mffolderpath } else {set mfwd $MFoutputfolder} if {$tfmfile != ""} { set plcmdline "tftopl [file join $MFdirfilename $MFbasefilename.tfm] [file join $MFdirfilename $MFbasefilename.plf]" set tfmfile "" } else { if {![file exists [file join $mfwd $MFbasefilename.tfm]]} { alertnote "Can't find file $MFbasefilename.tfm. Check your mode (no tfm in proof or smoke modes)." return } set plcmdline "tftopl [file join $mfwd $MFbasefilename.tfm] [file join $mfwd $MFbasefilename.plf]" } app::launchFore "CMTk" set plcmdline [curlyq $plcmdline] eval "AEBuild -r 'CMTk'" CMTX exec {----} [list $plcmdline] } "OzMF" { if {[app::isRunning OzMF]} { sendQuitEvent 'OzMF' alertnote "Click to proceed." } if {$mfset} { set mfwd $Mffolderpath } else {set mfwd $MFdirfilename} if {![file exists [file join $mfwd $MFbasefilename.tfm]]} { alertnote "Can't find file $MFbasefilename.tfm. Check that the \"delete_tfm\" flag in OzMetafont configs is set to false." return } app::launchFore "OzMF" if {$tfmfile != ""} { dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f $tfmfile set tfmfile "" } else { dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f [file join $mfwd $MFbasefilename.tfm] } } } } proc Mf::editlogProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars MfworkFolder mfAppSig gffile global tfmfile vplfile mfwd prefixplf prefixdvi switch $MfmodeVars(mfAppSig) { "CMT3" { if {![file exists [file join $MFoutputfolder $MFbasefilename.log]]} { alertnote "Can't find file $MFbasefilename.log." return } else { edit -r [file join $MFoutputfolder $MFbasefilename.log] } } "OzMF" { if {![file exists [file join $MFdirfilename $MFbasefilename.log]]} { alertnote "Can't find file $MFbasefilename.log. Check that the \"delete_log\" flag in OzMetafont configs is set to false." return } else { edit -r [file join $MFdirfilename $MFbasefilename.log] } } } } proc Mf::editplProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global rootname MfmodeVars MfworkFolder mfAppSig global mfwd tfmfile MFoutputfolder switch $MfmodeVars(mfAppSig) { "CMT3" { if {[file exists [file join $MFoutputfolder $MFbasefilename.plf]]} { edit -r [file join $MFoutputfolder $MFbasefilename.plf] } } "OzMF" { if {$tfmfile != ""} { if {[file exists [file join [file dirname $tfmfile] [file rootname [file tail $tfmfile]].pl]]} { edit -r [file join [file dirname $tfmfile] [file rootname [file tail $tfmfile]].pl] } else { alertnote "Can't find [file rootname [file tail $tfmfile]].pl" } } else { if {[file exists [file join $MFdirfilename $MFbasefilename.pl]]} { edit -r [file join $MFdirfilename $MFbasefilename.pl] } else { alertnote "Can't find $MFbasefilename.pl in $MFdirfilename." } } } } set prefixplf "" menu::buildSome otherFiles } proc Mf::dovplProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global rootname MfmodeVars MfworkFolder mfAppSig vplfile mfset global mfwd Mffolderpath MFoutputfolder switch $MfmodeVars(mfAppSig) { "CMT3" { if {[app::isRunning CMTm]} { sendQuitEvent 'CMTm' alertnote "Click to proceed." } if {$mfset} { set mfwd $Mffolderpath } else {set mfwd $MFoutputfolder} if {$vplfile != ""} { set plcmdline "vptovf [file join $MFdirfilename $MFbasefilename.vpl] [file join $MFdirfilename $MFbasefilename.vf] [file join $MFdirfilename $MFbasefilename.tfm]" set vplfile "" } else { if {![file exists [file join $mfwd $MFbasefilename.vpl]]} { alertnote "Can't find file $MFbasefilename.vpl." return } set plcmdline "tftopl [file join $mfwd $MFbasefilename.vpl] [file join $mfwd $MFbasefilename.vf] [file join $mfwd $MFbasefilename.tfm]" } app::launchFore "CMTm" set plcmdline [curlyq $plcmdline] eval "AEBuild -r 'CMTm'" CMTX exec {----} [list $plcmdline] } "OzMF" { if {[app::isRunning OzMF]} { sendQuitEvent 'OzMF' alertnote "Click to proceed." } if {$mfset} { set mfwd $Mffolderpath } else {set mfwd $MFdirfilename} if {![file exists [file join $mfwd $MFbasefilename.vpl]]} { alertnote "Can't find file $MFbasefilename.vpl." return } app::launchFore "OzMF" if {$vplfile != ""} { dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f $vplfile set vplfile "" } else { dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f [file join $mfwd $MFbasefilename.vpl] app::launchFore "ALFA" } } } } proc Mf::tftoplafolderProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars mfAppSig MFcurrentdir global filesindir ext Mffolderpath mfset catch {get_directory -p "Select a folder."} Mffolderpath if {$Mffolderpath == ""} { return } set MFcurrentdir $Mffolderpath Mf::tftoplallProc } proc Mf::tftoplcurrfoldProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars mfAppSig MFcurrentdir global filesindir ext Mffolderpath mfset if {$MFcurrentdir == ""} {alertnote "No folder currently selected" return} set prefixrmall "" set Mffolderpath $MFcurrentdir Mf::tftoplallProc } proc Mf::tftoplallProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars mfAppSig MFcurrentdir global filesindir ext Mffolderpath mfset set ext ".tfm" set mfset 1 set filesindir [glob -nocomplain -dir [file join $Mffolderpath] *$ext] if {[llength $filesindir] == 0} { alertnote "No \"$ext\" file in this folder." set mfset 0 return } switch [buttonAlert "Process all the tfm files in $Mffolderpath with tftopl ? " "yes" "cancel" ] { "yes" { foreach tfmfile $filesindir { Mf::setnames $tfmfile if {[file exists [file join $Mffolderpath $MFbasefilename.tfm]]} { Mf::doplProc app::launchFore "ALFA" } } } "cancel" {} } set mfset 0 switch $MfmodeVars(mfAppSig) { "CMT3" {set extpl "plf"} "OzMF" {set extpl "pl"} } foreach tfmfile $filesindir { Mf::setnames $tfmfile if {[file exists [file join $Mffolderpath $MFbasefilename.$extpl]]} { edit -r [file join $Mffolderpath $MFbasefilename.$extpl] } } menu::buildSome otherFiles } proc Mf::vptovfafolderProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global vplfile Mffolderpath MFcurrentdir global filesindir ext mfset catch {get_directory -p "Select a folder."} Mffolderpath set MFcurrentdir $Mffolderpath if {$Mffolderpath == ""} { return } Mf::vptovfallProc } proc Mf::vptovfcurrfoldProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global vplfile Mffolderpath MFcurrentdir global filesindir ext mfset if {$MFcurrentdir == ""} {alertnote "No folder currently selected" return} set prefixrmall "" set Mffolderpath: $MFcurrentdir Mf::vptovfallProc } proc Mf::vptovfallProc {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global vplfile Mffolderpath MFcurrentdir global filesindir ext mfset set ext "vpl" set mfset 1 set filesindir [glob -nocomplain -dir [file join $Mffolderpath] *.$ext] if {[llength $filesindir] == 0} { alertnote "No \"$ext\" file in this folder." set mfset 0 return } switch [buttonAlert "Process all the vpl files in $Mffolderpath with vptovf ? " "yes" "cancel" ] { "yes" { foreach vplfile $filesindir { Mf::setnames $vplfile edit -r "$vplfile" Mf::dovplProc app::launchFore "ALFA" } } "cancel" {} } set mfset 0 menu::buildSome otherFiles } ##################### # # # Utility procs # # # ##################### proc Mf::setnames {name} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars useWorkFold MfworkFolder set MFfullfilename $name set MFdirfilename [file dirname $name] set MFtailfilename [file tail $name] set MFbasefilename [file rootname [file tail $name]] set MFextfilename [file extension [file tail $name]] if {$MfmodeVars(useWorkFold) == 0} { set MFoutputfolder $MFdirfilename } else { set MFoutputfolder $MfmodeVars(MfworkFolder) } } proc Mf::getMfVersion {} { global MfmodeVars mfAppSig if {$MfmodeVars(mfAppSig) != "CMT3"} {return} set sig "CMT3" set vers [objectProperty 'MACS' vers "obj {want:type(file), seld:$sig, form:fcrt, from:'null'()}"] if {[regexp {\“.* (.*)©.*\”\}$} $vers longvers numvers]} { return [list [string trim $longvers "\r\}"] [string trim $numvers "\r\}"]] } else { beep message "Can't get version info" return } } # This proc looks in the current log file for a line indicating the name of # the output file produced by Metafont so that we do not have to calculate # the extension (which depends on the printer mode and the magnification) proc Mf::findgfFile {} { global MFfullfilename MFdirfilename MFtailfilename # global MFbasefilename MFextfilename MFoutputfolder # global MfmodeVars mfAppSig MfworkFolder MFoutputfolder global Mffolderpath mfwd mfset gffile switch $MfmodeVars(mfAppSig) { "CMT3" { if {$mfset} { set mfwd $Mffolderpath } else {set mfwd $MFoutputfolder} if {![file exists [file join $mfwd $MFbasefilename.log]]} { beep alertnote "Can't find file $MFbasefilename.log ; did you process $MFbasefilename.mf ?" return } catch {open [file join $mfwd $MFbasefilename.log]} fileId } "OzMF" { if {$mfset} { set mfwd $Mffolderpath } else {set mfwd [file dirname [win::Current]]} if {![file exists [file join $mfwd $MFbasefilename.log]]} { beep alertnote "Can't find file $MFbasefilename.log ; did you process $MFbasefilename.mf ? Check that the \"delete_log\" flag in OzMetafont configs is set to false." return } catch {open [file join $mfwd $MFbasefilename.log]} fileId } } catch {read $fileId} textlog regsub -all "\n" $textlog "" textlog set textlog [split $textlog] catch {lsearch -regexp $textlog .*gf} indx if {[expr {$indx > 0}]} { set gffile [lindex $textlog $indx] set gffile [file tail $gffile] return $gffile } else { alertnote "According to $MFbasefilename.log, no gf output written." return "" } } proc Mf::findmoderes {} { global MfmodeVars mfAppSig chosenMode if {$chosenMode == "proof"} { return [list "proof" "2602"] } if {$chosenMode == "smoke"} { return [list "smoke" "2602"] } if {[file exists $MfmodeVars(pathToModesMfFile) ]} { message "reading $MfmodeVars(pathToModesMfFile)" catch {open "$MfmodeVars(pathToModesMfFile)"} fileId catch {read $fileId} textlog # First we find the value of localfont if {$chosenMode == "localfont"} { regexp {localfont([^\;]*)\;} $textlog blabla localMfmode set localMfmode [string trim $localMfmode " :="] } elseif {$chosenMode == "smoke"} { set localMfmode $chosenMode } else { set localMfmode $MfmodeVars(mfModeForPrinter) } # Then we find the resolution in dpi set start [string first "mode_def $localMfmode" $textlog] if {$start == -1} { alertnote "Unknown mode $localMfmode." return } set textlog [string range $textlog $start end] regexp {pixels_per_inch[^0-9)]*([0-9]*)} $textlog blabla resdpi return [list $localMfmode $resdpi] } else { alertnote "Can't find file modes.mf : set the path in the Current Mode Prefs." return [list "proof" "2602"] } } proc Mf::checkMfoutputFolder {} { global MfmodeVars MfworkFolder MFoutputfolder if {$MFoutputfolder == "" } { catch {get_directory -p "Select the output folder"} rootpath set MFoutputfolder [set rootpath] addArrDef MfmodeVars MfworkFolder $rootpath } } proc Mf::findrootnameProc {} { global rootname set rootname [file rootname [file tail [win::Current]]] return } proc Mf::openMacroFile {flag name} { global MpmodeVars $flag if {[file exists $MpmodeVars($flag) ]} { message "opening $MpmodeVars($flag)" edit -r $MpmodeVars($flag) } else { alertnote "Can't find file $name : where is it ?" catch {getfile "Please locate $name"} chemin if {$chemin==""} {return} removeArrDef MpmodeVars $flag set $flag $chemin set MpmodeVars($flag) [set chemin] addArrDef MpmodeVars $flag $chemin edit -r $MpmodeVars($flag) } } proc Mf::openmodesmfProc {} {Mf::openMacroFile "pathToModesMfFile" "modes.mf"} proc Mf::openplainmfProc {} {Mf::openMacroFile "pathToPlainMfFile" "plain.mf"} proc Mf::deleteallfilesProc {ext} { global MfmodeVars MfworkFolder MFcurrentdir MFoutputfolder switch $MfmodeVars(mfAppSig) { "CMT3" { if {$MFcurrentdir == ""} { set MFcurrentdir $MFoutputfolder } } "OzMF" { if {$MFcurrentdir == ""} { set MFcurrentdir [file dirname [win::Current]] } } } if {![regexp "gf" $ext] && ![regexp "pk" $ext]} { set ext ".$ext" } set filesindir [glob -nocomplain -dir [file join $MFcurrentdir] *$ext] switch [buttonAlert "OK to remove all \"$ext\" files from $MFcurrentdir ?" "yes" "cancel" ] { "yes" { set longueur [llength $filesindir] if {$longueur == 0} { alertnote "No \"$ext\" file in output folder." return } foreach Mffile $filesindir { file delete $Mffile message "$longueur file(s) removed" } } "cancel" {return} } } proc Mf::allAuxfilesProc {ext} { global Mffolderpath set filesindir [glob -nocomplain -dir [file join $Mffolderpath] *.$ext] if {![llength $filesindir]} { alertnote "No \"$ext\" files in folder $Mffolderpath" return } foreach MFfile $filesindir { if {[file exists "$MFfile"]} { edit -r $MFfile } } } proc Mf::sourceFilesProc {menu item} { global mfPaths MfmodeVars pathToSourceFolder buildSourceFiles nestingDepth mfsymb if {$item == "Rebuild Source List"} { if {!$MfmodeVars(buildSourceFiles) || $MfmodeVars(pathToSourceFolder) == "" } { alertnote "You must set the \ \"Path To Source Folder\" and check the \"Build Source Files\" checkbox in the mode preferences." } else { Mf::shadowList "" } } else { set upfold $menu eval [concat set upfold \[string trimleft $menu \"$mfsymb\"\]] set upfold [file join $upfold $item] edit $mfPaths($upfold) } } ################################ # # # Insert commands submenus # # # ################################ proc Mf::newtemplateProc {} { global MfmodeVars userBeginchar userEndchar global MfmodeVars myName myEMail myWebPage new -n "newfont.mf" # Ask how many chars in the font beep catch {prompt "How many chars in the new font ?" 128} nbchr if {$nbchr == "cancel"} { return } elseif {![is::PositiveInteger $nbchr]} { beep message "invalid input: please enter a positive integer" return } if {$MfmodeVars(myName)=="" & $MfmodeVars(myEMail)=="" & $MfmodeVars(myWebPage)=="http://"} { alertnote "You should declare your name, e-mail address and Web page in the Mode Prefs to have them automatically inserted in the preambule." } goto 0 # Preambule instruction set t "\% This file : •\n" append t "\% Created : [Mf::creationdate]\n" append t "\% Author : $MfmodeVars(myName)\n" append t "\% e-mail : <$MfmodeVars(myEMail)>\n" append t "\% Web-page : <$MfmodeVars(myWebPage)>\n" append t "\% Comments : •\n% \n% \n% \n\n" append t "font_size •pt\#; \% the \"design size\" of this font\n\n" append t "mode_setup;" append t "\n\n\%\%\%\% Parameters \%\%\%\%\n\n" append t "\n\n\%\%\%\% Pixellisation \%\%\%\%\n\n" append t "define_pixels(•);\n" append t "define_whole_pixels(•);\n" append t "define_whole_vertical_pixels(•);\n" append t "define_blacker_pixels(•);\n" append t "define_good_x_pixels(•);\n" append t "define_good_y_pixels(•);\n" append t "define_corrected_pixels(•);\n" append t "define_horizontal_corrected_pixels(•);\n" append t "\n\n\%\%\%\% Macros and definitions \%\%\%\%\n\n" append t "\n\n\%\%\%\% Drawing instructions for the characters \%\%\%\%\n\n" insertText $t set i 0 for {set i 0} {$i < $nbchr} {incr i} { insertText "$MfmodeVars(userBeginchar)([set i],•,•,•);\"•\";\n\n\n\n$MfmodeVars(userEndchar);\n\n" } # Postambule instruction set t "\n\n\%\%\%\% Ligtables and kerning \%\%\%\%\n\n" append t "ligtable \"•\": \"•\" kern • \#;\n" append t "\n\n\%\%\%\% General Font Parameters \%\%\%\%\n\n" append t "font_slant:=• ;\t\t\t\% slant per point\n" append t "font_normal_space:=• ;\t\t\% interword spacing\n" append t "font_normal_stretch:=• ;\t\% stretchability of interword spacing\n" append t "font_normal_shrink:=•;\t\t\% shrinkability of interword spacing\n" append t "font_x_height:=• ;\t\t\% TeX's ex unit\n" append t "font_quad:=• ;\t\t\t\% TeX's em unit\n" append t "font_extra_space:=• ;\t\t\% additional spacing between sentences\n" append t "\nfont_coding_scheme:= \"•\";\t\% coding scheme (optional)\n" append t "font_identifier:= \"•\";\t\t\% family (optional)\n" append t "\n\nbye" insertText $t goto 0 } proc Mf::creationdate {} { set date [lindex [mtime [now] long] 0] append date " - [lindex [mtime [now] long] 1]" return $date } proc Mf::variablesProc {menu item} { switch $item { " boolean" {insertObject "boolean ••;\n••"} " numeric" {insertObject "numeric ••;\n••"} " pair" {insertObject "pair ••;\n••"} " path" {insertObject "path ••;\n••"} " pen" {insertObject "pen ••;\n••"} " picture" {insertObject "picture ••;\n••"} " string" {insertObject "string ••;\n••"} " transform" {insertObject "transform ••;\n••"} " newinternal" {insertObject "newinternal ••;\n••"} } } proc Mf::booleanProc {menu item} { switch $item { " charexists" {insertObject "charexists "} " cycle" {insertObject "cycle "} " false" {insertObject "false "} " known" {insertObject "known "} " true" {insertObject "true "} " unknown" {insertObject "unknown "} } } proc Mf::functionsProc {menu item} { switch $item { " angle" {insertObject "angle ••;\n••"} " ceilling" {insertObject "ceilling ••;\n••"} " floor" {insertObject "floor(••)••"} " cosd" {insertObject "cosd(••)••"} " sind" {insertObject "sind(••)••"} " mexp" {insertObject "mexp(••)••"} " mlog" {insertObject "mlog(••)••"} " sqrt" {insertObject "sqrt(••)••"} " dotprod" {insertObject "dotprod •• = ••;\n••"} " eps" {insertObject "eps "} " epsilon" {insertObject "epsilon "} " infinity" {insertObject "infinity "} " round" {insertObject "round(••)••"} " hround" {insertObject "hround(••)••"} " vround" {insertObject "vround(••)••"} " solve" {insertObject "solve ••(••,••);\n••"} " tolerance" {insertObject "tolerance:= ••;\n••"} " normaldeviate" {insertObject "normaldeviate(••)••"} " randomseed" {insertObject "randomseed:= ••;\n••"} " uniformdeviate" {insertObject "uniformdeviate(••)••"} " whatever" {insertObject "whatever "} } } proc Mf::positioningProc {menu item} { switch $item { " clearxy" {insertObject "clearxy ••;\n••"} " direction" {insertObject "direction •• of ••"} " directionpoint" {insertObject "directionpoint •• of ••"} " directiontime" {insertObject "directiontime •• of ••;\n••"} " penoffset" {insertObject "penoffset •• of ••"} " point…of" {insertObject "point •• of ••"} " precontrol…of" {insertObject "precontrol •• of ••"} " postcontrol…of" {insertObject "postcontrol •• of ••"} " intersectionpoint" {insertObject " •• intersectionpoint ••"} " intersectiontimes" {insertObject "•• intersectiontimes ••"} " good.bot" {insertObject "good.bot "} " good.lft" {insertObject "good.lft "} " good.rt" {insertObject "good.rt "} " good.top" {insertObject "good.top "} " good.x" {insertObject "good.x "} " good.y" {insertObject "good.y "} " xpart" {insertObject "xpart(••)••"} " xxpart" {insertObject "xxpart(••)••"} " xypart" {insertObject "xypart(••)••"} " ypart" {insertObject "ypart(••)••"} " yxpart" {insertObject "yxpar(••)••"} " yypart" {insertObject "yypart(••)••"} } } proc Mf::pathsProc {menu item} { switch $item { " penstroke" {insertObject "penstroke ••;\n••"} " build…penstroke" {Mf::penstrokeProc} " flex" {Mf::mkflexProc} " fullcircle" {insertObject "fullcircle "} " halfcircle" {insertObject "halfcircle "} " quartercircle" {insertObject "quartercircle "} " superellipse" {insertObject "superellipse(••,••,••,••,••);\n••"} " unitsquare" {insertObject "unitsquare "} " makepath" {insertObject "makepath ••;\n••"} " interpath" {insertObject "interpath(••,••,••);\n••"} " subpath" {insertObject "subpath(••,••) of ••"} " tensepath" {insertObject "tensepath "} " counterclockwise" {insertObject "counterclockwise "} " reverse" {insertObject "reverse "} " turningnumber" {insertObject "turningnumber "} } } proc Mf::pensProc {menu item} { switch $item { " clear_pen_memory" {insertObject "clear_pen_memory;"} " clearpen" {insertObject "clearpen;"} " currentpen" {insertObject "currentpen "} " makepen" {insertObject "makepen "} " nullpen" {insertObject "nullpen;"} " savepen" {insertObject "••:=savepen;••"} " pencircle" {insertObject "pencircle "} " pickup…pencircle" {insertObject "pickup pencircle "} " pencircle…scaled" {insertObject "pencircle •• xscaled •• yscaled ••;\n••"} " pickup…pencircle…scaled" {insertObject "pickup pencircle •• xscaled •• yscaled ••;\n••"} " pensquare" {insertObject "pensquare "} " pickup…pensquare" {insertObject "pickup pensquare "} " pensquare…scaled" {insertObject "pensquare •• xscaled •• yscaled ••;\n••"} " pickup…pensquare…scaled" {insertObject "pickup pensquare •• xscaled •• yscaled ••;\n••"} " penrazor" {insertObject "penrazor;"} " penspeck" {insertObject "penspeck;"} " penpos" {insertObject "penpos••(••,••);\n••"} " pen_bot" {insertObject "pen_bot"} " pen_lft" {insertObject "pen_lft"} " pen_rt" {insertObject "pen_rt"} " pen_top" {insertObject "pen_top"} " pickup" {insertObject "pickup "} } } proc Mf::picturesProc {menu item} { switch $item { " blankpicture" {insertObject "blankpicture"} " clearit" {insertObject "clearit ••;\n••"} " currentpicture" {insertObject "currentpicture"} " nullpicture" {insertObject "nullpicture"} " totalweight" {insertObject "totalweight "} " unitpixel" {insertObject "unitpixel"} } } proc Mf::stringsProc {menu item} { switch $item { " ditto" {insertObject "ditto"} " jobname" {insertObject "jobname"} " readstring" {insertObject "••:=readstring;••"} " substring" {insertObject "substring(••,••) of ••"} } } proc Mf::transformationsProc {menu item} { switch $item { " currenttransform" {insertObject "currenttransform "} " identity" {insertObject "identity "} " inverse" {insertObject "inverse "} " reflectedabout" {insertObject "reflectedabout(••,••) ••"} " rotated" {insertObject "rotated "} " rotatedaround" {insertObject "rotatedaround(••,••) ••"} " scaled" {insertObject "scaled "} " shifted" {insertObject "shifted "} " slanted" {insertObject "slanted "} " transformed" {insertObject "transformed "} " xscaled" {insertObject "xscaled "} " yscaled" {insertObject "yscaled "} " zscaled" {insertObject "zscaled "} } } proc Mf::definitionsProc {menu item} { switch $item { " def…enddef" {insertObject "def ••=\n••\nenddef;\n••"} " suffix" {insertObject "(suffix ••)••"} " expr" {insertObject "(expr ••)••"} " text" {insertObject "(text ••)••"} " primarydef…enddef" {insertObject "primarydef ••=\n••\nenddef;\n••"} " secondarydef…enddef" {insertObject "secondarydef ••=\n••\nenddef;\n••"} " tertiarydef…enddef" {insertObject "tertiarydef ••=\n••\nenddef;\n••"} " vardef…enddef" {insertObject "vardef ••=\n••\nenddef;\n••"} " begingroup…endgroup" {insertObject "begingroup ••\n\nendgroup;\n••"} } } proc Mf::conditionsProc {menu item} { switch $item { " for…endfor" {insertObject "for •• : •• endfor;\n••"} " forever…endfor" {insertObject "forever •• endfor;\n••"} " forsuffixes…endfor" {insertObject "forsuffixes •• : •• endfor;\n••"} " if…fi" {insertObject "if •• : •• fi\n••"} " if…elseif…else…fi" {insertObject "if •• elseif •• else •• fi\n••"} " downto" {insertObject "downto "} " upto" {insertObject "upto "} " step…until" {insertObject "step •• until •• : ••"} " exitif" {insertObject "exitif ••;"} " exitunless" {insertObject "exitunless ••;"} } } proc Mf::drawingProc {menu item} { switch $item { " addto…also" {insertObject "addto •• also ••;\n••"} " addto…currentpicture" {insertObject "addto currentpicture also currentpicture;\n••"} " addto…contour" {insertObject "addto •• contour •• ;\n••"} " addto…contour…withpen" {insertObject "addto •• contour •• withpen ••;\n••"} " addto…contour…withweight" {insertObject "addto •• contour •• withweight ••;\n••"} " addto…doublepath" {insertObject "addto •• doublepath ••;\n••"} " addto…doublepath…withpen" {insertObject "addto •• doublepath •• withpen ••;\n••"} " addto…doublepath…withweight" {insertObject "addto •• doublepath •• withweight ••;\n••"} " cull…dropping" {insertObject "cull •• dropping (••,••);\n••"} " cull…dropping…withweight" {insertObject "cull •• dropping (••,••) withweight ••;\n••"} " cull…keeping" {insertObject "cull •• keeping (••,••);\n••"} " cull…keeping…withweight" {insertObject "cull •• keeping (••,••) withweight ••;\n••"} " cullit" {insertObject "cullit ••;\n••"} " cutdraw" {insertObject "cutdraw "} " cutoff" {insertObject "cutoff(••,••);\n••"} " draw" {insertObject "draw "} " drawdot" {insertObject "drawdot ••;\n••"} " erase" {insertObject "erase ••;\n••"} " fill" {insertObject "fill ••;\n••"} " filldraw" {insertObject "filldraw ••;\n••"} " undraw" {insertObject "undraw "} " undrawdot" {insertObject "undrawdot ••;\n••"} " unfill" {insertObject "unfill ••;\n••"} " unfilldraw" {insertObject "unfilldraw ••;\n••"} } } proc Mf::charactersProc {menu item} { global MfmodeVars userBeginchar userEndchar switch $item { " beginchar…endchar" {insertObject "$MfmodeVars(userBeginchar)(\"••\",••,••,••);\"••\";\n••\n$MfmodeVars(userEndchar);\n••"} " extra_beginchar" {insertObject "extra_beginchar:=\" •• \";\n••"} " extra_endchar" {insertObject "extra_endchar:=\" •• \";\n••"} } } proc Mf::unitsProc {menu item} { switch $item { " blacker" {insertObject "blacker:=••;\n••"} " fillin" {insertObject "fillin:=••;\n••"} " o_correction" {insertObject "o_correction:= ••;\n••"} " fix_units" {insertObject "fix_units;\n"} " mode_setup" {insertObject "mode_setup;\n"} " pixels_per_inchs" {insertObject "pixels_per_inchs:=••;\n••"} " aspect_ratio" {insertObject "aspect_ratio:=••;\n••"} } } proc Mf::pixellisationProc {menu item} { switch $item { " define_pixels" {insertObject "define_pixels(••);\n••"} " define_blacker_pixels" {insertObject "define_blacker_pixels(••);\n••"} " define_good_x_pixels" {insertObject "define_good_x_pixels(••);\n••"} " define_good_y_pixels" {insertObject "define_good_y_pixels(••);\n••"} " define_corrected_pixels" {insertObject "define_corrected_pixels(••);\n••"} " define_horizontal_corrected_pixels" {insertObject "define_horizontal_corrected_pixels(••);\n••"} " define_whole_pixels" {insertObject "define_whole_pixels(••);\n••"} " define_whole_blacker_pixels" {insertObject "define_whole_blacker_pixels(••);\n••"} " define_whole_vertical_pixels" {insertObject "define_whole_vertical_pixels(••);\n••"} " define_whole_vertical_blacker_pixels" {insertObject "define_whole_vertical_blacker_pixels(••);\n••"} } } proc Mf::fontInternalsProc {menu item} { switch $item { " charlist" {insertObject "charlist ••: •• : •• : •• : ••"} " extensible" {insertObject "extensible ••: ••, ••, ••, ••"} " font_coding_scheme" {insertObject "font_coding_scheme:= \"••\";\n••"} " font_extra_space" {insertObject "font_extra_space:= ••;\n••"} " font_identifier" {insertObject "font_identifier:= \"••\";\n••"} " font_normal_shrink" {insertObject "font_normal_shrink:= ••;\n••"} " font_normal_space" {insertObject "font_normal_space:= ••;\n••"} " font_normal_stretch" {insertObject "font_normal_stretch:= ••;\n••"} " font_quad" {insertObject "font_quad:= ••;\n••"} " font_size" {insertObject "font_size:= ••;\n••"} " font_slant" {insertObject "font_slant:= ••;\n••"} " font_x_height" {insertObject "font_x_height:= ••;\n••"} " fontdimen" {insertObject "fontdimen ••: ••, ••, ••, ••\n••"} " headerbytes" {insertObject "headerbytes ••: ••, ••, ••, ••"} " ligtable" {insertObject "ligtable \"••\" : \"••\" =: oct\"••\";\n••"} " kern" {insertObject "kern ••\#••"} } } proc Mf::displayingProc {menu item} { switch $item { " currentwindow" {insertObject "currentwindow:= ••;\n••"} " display…inwindow" {insertObject "display •• inwindow ••;\n••"} " openwindow…from…to…at" {insertObject "openwindow •• from (••,••) to (••,••) at (••,••);\n••"} " screen_cols" {insertObject "screen_cols:= ••;\n••"} " screen_rows" {insertObject "screen_rows:= ••;\n••"} " screenrule" {insertObject "screenrule(••,••);\n••"} } } proc Mf::outputProc {menu item} { switch $item { " openit" {insertObject "openit;\n"} " shipit" {insertObject "shipit;\n"} " showit" {insertObject "showit;\n"} " labels" {insertObject "labels(••);\n••"} " labels…range…thru" {insertObject "labels(range •• thru ••);\n••"} " penlabels" {insertObject "penlabels(••);\n••"} " makelabel" {insertObject "makelabel(\"••\",••);\n••"} " makegrid..." {Mf::mkgridProc} " proofoffset" {insertObject "proofoffset(••,••);\n••"} " proofrule" {insertObject "proofrule(••,••);\n••"} " proofrulethickness" {insertObject "proofrulethickness:=••;\n••"} " grayfont" {insertObject "grayfont \"••\";\n••"} " labelfont" {insertObject "labelfont \"••\";\n••"} " slantfont" {insertObject "slantfont \"••\";\n••"} " titlefont" {insertObject "titlefont \"••\";\n••"} } } proc Mf::debuggingProc {menu item} { switch $item { " errhelp" {insertObject "errhelp "} " errmessage" {insertObject "errmessage \"••\";\n••"} " message" {insertObject "message \"••\";\n••"} " stop" {insertObject "stop;\n"} " show" {insertObject "show ••;\n••"} " showdependencies" {insertObject "showdependencies;\n"} " showstats" {insertObject "showstats;\n"} " showtoken" {insertObject "showtoken ••;\n••"} " showvariable" {insertObject "showvariable ••;\n••"} " loggingall" {insertObject "loggingall:= ••\n••"} " tracingall" {insertObject "tracingall;\n"} " tracingnone" {insertObject "tracingnone;\n"} " batchmode" {insertObject "batchmode;\n"} " errorstopmode" {insertObject "errorstopmode;\n"} " nonstopmode" {insertObject "nonstopmode;\n"} " scrollmode" {insertObject "scrollmode;\n"} } } proc Mf::miscProc {menu item} { switch $item { " capsule_def" {insertObject "capsule_def ••;\n••"} " expandafter" {insertObject "expandafter "} " gobble" {insertObject "gobble "} " gobbled" {insertObject "gobbled "} " interact" {insertObject "interact;\n••"} " numtok" {insertObject "numtok "} " scantokens" {insertObject "scantokens "} " special" {insertObject "special \" ••\";\n••"} " numspecial" {insertObject "numspecial ••;\n••"} } } proc Mf::varintProc {menu item} { switch $item { " autorounding" {insertObject "autorounding:= ••;\n••"} " designsize" {insertObject "designsize:= ••;\n••"} " fontmaking" {insertObject "fontmaking:= ••;\n••"} " granularity" {insertObject "granularity:= ••;\n••"} " pausing" {insertObject "pausing:= ••;\n••"} " proofing" {insertObject "proofing:= ••;\n••"} " showstopping" {insertObject "showstopping:= ••;\n••"} " smoothing" {insertObject "smoothing:= ••;\n••"} " charcode" {insertObject "charcode:= ••;\n••"} " chardp" {insertObject "chardp:= ••;\n••"} " chardx" {insertObject "chardx:= ••;\n••"} " chardy" {insertObject "chardy:= ••;\n••"} " charext" {insertObject "charext:= ••;\n••"} " charht" {insertObject "charht:= ••;\n••"} " charic" {insertObject "charic:= ••;\n••"} " charwd" {insertObject "charwd:= ••;\n••"} " hppp" {insertObject "hppp:= ••;\n••"} " vppp" {insertObject "vppp:= ••;\n••"} " xoffset" {insertObject "xoffset:= ••;\n••"} " yoffset" {insertObject "yoffset:= ••;\n••"} " day" {insertObject "day;"} " month" {insertObject "month;"} " year" {insertObject "year;"} " time" {insertObject "time;"} " tracingcapsules" {insertObject "tracingcapsules:= ••;\n••"} " tracingchoices" {insertObject "tracingchoices:= ••;\n••"} " tracingcommands" {insertObject "tracingcommands:= ••;\n••"} " tracingedges" {insertObject "tracingedges:= ••;\n••"} " tracingequations" {insertObject "tracingequations:= ••;\n••"} " tracingmacros" {insertObject "tracingmacros:= ••;\n••"} " tracingonline" {insertObject "tracingonline:= ••;\n••"} " tracingoutput" {insertObject "tracingoutput:= ••;\n••"} " tracingpens" {insertObject "tracingpens:= ••;\n••"} " tracingrestores" {insertObject "tracingrestores:= ••;\n••"} " tracingspecs" {insertObject "tracingspecs:= ••;\n••"} " tracingstats" {insertObject "tracingstats:= ••;\n••"} " tracingtitles" {insertObject "tracingtitles:= ••;\n••"} " turningcheck" {insertObject "turningcheck:= ••;\n••"} " warningcheck" {insertObject "warningcheck:= ••;\n••"} } } # In this proc, choose the number of horizontal and vertical lines in a grid proc Mf::mkgridProc {} { set macroName "makegrid" beep catch {prompt "$macroName: how many x-coordinates ?" 3} numbx if {$numbx == "cancel"} { return } elseif {![is::PositiveInteger $numbx]} { beep message "invalid input: please enter a positive integer" return } catch {prompt "$macroName: how many y-coordinates ?" 3} numby if {$numby == "cancel"} { return } elseif {![is::PositiveInteger $numby]} { beep message "invalid input: please enter a positive integer" return } if {$numbx && $numby} { set body "makegrid(••" for {set i 1} {$i < $numbx} {incr i} { append body ",••" } append body ")(••" for {set i 1} {$i < $numby} {incr i} { append body ",••" } append body ");\n••" } else { set body "••\r" } insertObject $body } # In this proc, choose the number of points on a flex path proc Mf::mkflexProc {} { set macroName "flex" beep catch {prompt "$macroName: how many points on the flex-path ?" 3} numbp if {$numbp == "cancel"} { return } elseif {![is::PositiveInteger $numbp]} { beep message "invalid input: please enter a positive integer" return } if {$numbp} { set body "flex(••" for {set i 1} {$i < $numbp} {incr i} { append body ",••" } append body ") ••" } else { set body "••\r" } insertObject $body } # In this proc, choose the number of points on a penstroke proc Mf::penstrokeProc {} { set macroName "penstroke" beep catch {prompt "$macroName: how many points on the penstroke ?" 3} numbp if {$numbp == "cancel"} { return } elseif {![is::PositiveInteger $numbp]} { beep message "invalid input: please enter a positive integer" return } if {$numbp} { set body "penstroke z1e" for {set i 2} {$i < [expr {$numbp + 1}]} {incr i} { append body "..z${i}e" } append body " ;" } else { set body "••\r" } insertObject $body } ############################# # # # Mode specific goodies # # # ############################# ######### Syntax Coloring ########### # We define two groups of keywords : # - the macros of the Metafont plain format. Default color : blue # - the Metafont primitives. Default color : magenta # These colors can be modified in the mode prefs : see "Keyword Color" # and "Primitives Color". set mfKeyWords { abs beginchar blacker blankpicture bot bye byte capsule_def ceilling change_width checksum clear_pen_memory clearit clearpen clearxy codingscheme counterclockwise cullit currentpen currentpicture currenttransform currentwindow cutdraw cutoff decr define_blacker_pixels define_good_x_pixels define_good_y_pixels define_pixels define_whole_pixels direction directionpoint displaying ditto dotprod downto draw drawdot endchar eps epsilon erase exitunless extra_beginchar extra_endchar extraspace face family fill filldraw fix_units flex font_coding_scheme font_extra_space font_identifier font_normal_shrink font_normal_space font_normal_stretch font_quad font_size font_slant font_x_height fontdimen fullcircle gfcorners gobble gobbled good.bot good.lft good.rt good.top good.x good.y grayfont halfcircle hide hround identity imagerules incr infinity interact interpath intersectionpoint inverse italcorr join_radius label labelfont labels lft loggingall makegrid makelabel max min mod mode_setup nextlarger nodisplays notransforms numtok o_correction of openit openwindow or pen_bot pen_lft pen_rt pen_top penlabels penpos penrazor penspeck pensquare penstroke pickup pixels_per_inchs proofoffset proofrule proofrulethickness quad quartercircle range reflectedabout relax rep rotatedaround round rt savepen screen_cols screen_rows screenchars screenrule screenstrokes secondary shipit showit shrink slant slantfont solve space stop stretch superellipse tensepath text thru titlefont tolerance top tracingall tracingnone undraw undrawdot unfill unfilldraw unitpixel unitsquare upto varchar vround whatever xheight } regModeKeywords -e {%} -c $MfmodeVars(commentColor) \ -k $MfmodeVars(keywordColor) -s $MfmodeVars(stringColor) Mf $mfKeyWords unset mfKeyWords set mfprimKeyWords { ASCII addto also and angle at atleast autorounding batchmode begingroup boolean char character charcode chardp chardx chardy charexists charext charht charic charlist charwd comment contour controls cosd cull curl cycle day decimal def delimiters designsize designunits directiontime display doublepath dump dropping else elseif end enddef endfor endgroup endinput errhelp errmessage errorstopmode everyjob exitif expandafter expr extensible false fi fillin floor fontdimen fontmaking fontname fontdsize fontat forever forsuffixes from granularity headerbytes hex hppp if inner input interim intersectiontimes inwindow jobname keeping kern known krn length let lig ligtable makepath makepen map mapfont message mexp mlog month newinternal nonstopmode normaldeviate not nullpen nullpicture numeric numspecial oct odd openwindow outer pair parameter path pausing pen pencircle penoffset picture point postcontrol precontrol primary primarydef proofing quote randomseed readstring reverse rotated save scaled scantokens scrollmode secondarydef setchar shifted shipout show showdependencies showstats showstopping showtoken showvariable sind slanted smoothing special sqrt step str string subpath substring suffix tension tertiary tertiarydef time to totalweight tracingcapsules tracingchoices tracingcommands tracingedges tracingequations tracingmacros tracingonline tracingoutput tracingpens tracingrestores tracingspecs tracingstats tracingtitles transform transformed true turningcheck turningnumber uniformdeviate unknown until vardef vppp warningcheck withpen withweight xoffset xpart xscaled xxpart xypart year yoffset ypart yscaled yxpart yypart zscaled } regModeKeywords -a -k $MfmodeVars(primitivesColor) Mf $mfprimKeyWords # We store the primitives in a list which will be used below by the Mf::DblClick proc. set Mfprimlist [split $mfprimKeyWords] # We don't need mfprimKeyWords anymore : unset mfprimKeyWords ############ Completions ################ set completions(Mf) {contraction Input completion::cmd completion::electric} set Mfcmds { addto also angle ASCII atleast autorounding batchmode beginchar begingroup blacker blankpicture boolean byte capsule_def ceilling change_width char character charcode chardp chardx chardy charexists charext charht charic charlist charwd checksum clearit clearpen clearxy clear_pen_memory codingscheme comment contour controls cosd counterclockwise cull cullit curl currentpen currentpicture currenttransform currentwindow cutdraw cutoff cycle decimal decr define_blacker_pixels define_good_x_pixels define_good_y_pixels define_pixels define_whole_pixels delimiters designsize direction directionpoint directiontime display displaying ditto dotprod doublepath downto draw drawdot dropping dump else elseif endchar enddef endfor endgroup endinput epsilon erase errhelp errmessage errorstopmode everyjob exitif exitunless expandafter expr extensible extraspace extra_beginchar extra_endchar face false family fill filldraw fillin fix_units flex floor fontdimen fontmaking font_coding_scheme font_extra_space font_identifier font_normal_shrink font_normal_space font_normal_stretch font_quad font_size font_slant font_x_height forever forsuffixes from fullcircle gfcorners gobble gobbled good.bot good.lft good.rt good.top good.x good.y granularity grayfont halfcircle headerbytes hide hppp hround identity imagerules incr infinity inner input interact interim interpath intersectionpoint intersectiontimes inverse inwindow italcorr jobname join_radius keeping kern known label labelfont labels length ligtable loggingall makegrid makelabel makepath makepen message mexp mlog mode_setup month newinternal nextlarger nodisplays nonstopmode normaldeviate notransforms nullpen nullpicture numeric numspecial numtok openit openwindow outer o_correction pair path pausing pencircle penlabels penoffset penpos penrazor penspeck pensquare penstroke pen_bot pen_lft pen_rt pen_top pickup picture pixels_per_inchs point postcontrol precontrol primary primarydef proofing proofoffset proofrule proofrulethickness quad quartercircle quote randomseed range readstring reflectedabout relax reverse rotated rotatedaround round save savepen scaled scantokens screenchars screenrule screenstrokes screen_cols screen_rows scrollmode secondary secondarydef shifted shipit shipout show showdependencies showit showstats showstopping showtoken showvariable shrink sind slant slanted slantfont smoothing solve space special sqrt step stop stretch string subpath substring suffix superellipse tensepath tension tertiary tertiarydef text thru time titlefont tolerance totalweight tracingall tracingcapsules tracingchoices tracingcommands tracingedges tracingequations tracingmacros tracingnone tracingonline tracingoutput tracingpens tracingrestores tracingspecs tracingstats tracingtitles transform transformed true turningcheck turningnumber undraw undrawdot unfill unfilldraw uniformdeviate unitpixel unitsquare unknown until upto varchar vardef vppp vround warningcheck whatever withpen withweight xheight xoffset xpart xscaled xxpart xypart year yoffset ypart yscaled yxpart yypart zscaled } # # # # # Abbreviations # # # # # set Mfelectrics(bc) "◊kill0$MfmodeVars(userBeginchar)(\"••\",••,••,••);\"••\";\n••\n\n$MfmodeVars(userEndchar);\n••" set Mfelectrics(bg) "◊kill0begingroup ••\n\nendgroup;\n••" set Mfelectrics(dp) "◊kill0define_pixels(••);\n••" set Mfelectrics(dbp) "◊kill0define_blacker_pixels(••);\n••" set Mfelectrics(dcp) "◊kill0define_corrected_pixels(••);\n••" set Mfelectrics(dgxp) "◊kill0define_good_x_pixels(••);\n••" set Mfelectrics(dgyp) "◊kill0define_good_y_pixels(••);\n••" set Mfelectrics(dhcp) "◊kill0define_horizontal_corrected_pixels(••);\n••" set Mfelectrics(dwp) "◊kill0define_whole_pixels(••);\n••" set Mfelectrics(dwvp) "◊kill0define_whole_vertical_pixels(••);\n••" set Mfelectrics(dwvb) "◊kill0define_whole_vertical_blacker_pixels(••);\n••" set Mfelectrics(sc) "◊kill0screen_cols:= ••;" set Mfelectrics(sr) "◊kill0screen_rows:= ••;" set Mfelectrics(xpa) "◊kill0expandafter " set Mfelectrics(for) " •• : •• endfor;\n••" set Mfelectrics(def) " ••=\n••\nenddef;\n••" set Mfelectrics(prim) "◊kill0primarydef ••=\n••\nenddef;\n••" set Mfelectrics(sec) "◊kill0secondarydef ••=\n••\nenddef;\n••" set Mfelectrics(ter) "◊kill0tertiarydef ••=\n••\nenddef;\n••" set Mfelectrics(vardef) " ••=\n••\nenddef;\n••" set Mfelectrics(forever) " •• endfor;\n••" set Mfelectrics(forsuf) " •• : •• endfor;\n••" set Mfelectrics(if) " •• : •• fi\n••" # # # # # contractions # # # # # set Mfelectrics(cu'n) "◊kill0currentpen " set Mfelectrics(cu'p) "◊kill0currentpicture " set Mfelectrics(cu't) "◊kill0currenttransform " set Mfelectrics(cu'w) "◊kill0currentwindow " set Mfelectrics(di'p) "◊kill0directionpoint " set Mfelectrics(di't) "◊kill0directiontime " set Mfelectrics(re'a) "◊kill0reflectedabout(••,••) ••" set Mfelectrics(ro'a) "◊kill0rotatedaround(••,••) ••" # Proc to complete the 'input' instructions. Type 'input xx' and the proc # will look for a known mf file whose name starts with 'xx'. This proc # searches among the mf files in the source directory defined in the mode # prefs (and in ALL its subfolders). If the source directory hasn't been # defined, it searches in the current folder and its subfolders. proc Mf::Completion::Input {dummy} { global MFfilenames global mfSubmenuItems MfmodeVars pathToSourceFolder buildSourceFiles nestingDepth if {!$MfmodeVars(buildSourceFiles)} { set MFfilenames {} Mf::listSrcInDir [file dirname [win::Current]] mf } set MFfilenames [join $MFfilenames] regsub -all " " $MFfilenames " " MFfilenames set cmd [completion::lastTwoWords begin] if { [string trim $begin] != "input" } { return 0 } completion::Find $cmd [completion::fromList $cmd MFfilenames] } ############ Key Bindings ################ # We define Metafont specific key bindings : all of them # use 'ctrl-m' followed by a letter. # Key bindings to choose the processing mode : # hit ctrl-m and then one of the letters p, s, l or u to select # respectively proof, smoke, localfont or user defined modes. Bind 'm' <z> prefixChar Mf Bind 'p' <M> {Mf::choosemodeProc "metafontMode" "proof"} Mf Bind 's' <M> {Mf::choosemodeProc "metafontMode" "smoke"} Mf Bind 'l' <M> {Mf::choosemodeProc "metafontMode" "localfont"} Mf Bind 'u' <M> {Mf::choosemodeProc "metafontMode" "userDefined"} Mf # Now key bindings to process the <b>uffer, a <f>ile or a <d>irectory : # 'ctrl-m b', 'ctrl-m f' and 'ctrl-m d' respectively. Bind 'b' <M> {Mf::menuProc "Metafont" "runTheBuffer"} Bind 'f' <M> {Mf::menuProc "Metafont" "runAFile"} Bind 'd' <M> {Mf::runafolderProc} # A key binding ('ctrl-m n') to create a new font template : Bind 'n' <M> {Mf::newtemplateProc} Mf # A key binding ('ctrl-m m') to edit the <m>odes file modes.mf : Bind 'm' <M> {Mf::openmodesmfProc} Mf # A key binding ('ctrl-m c') to edit the macro <c>ommands file plain.mf : Bind 'c' <M> {Mf::openplainmfProc} Mf # A key binding ('ctrl-m g') to edit the log file : Bind 'g' <M> {Mf::setnames [win::Current] ; Mf::editlogProc} Mf # A key binding ('ctrl-m t') to convert <t>fm file to pl : Bind 't' <M> {Mf::setnames [win::Current];Mf::doplProc;set prefixplf "";menu::buildSome otherFiles;Mf::editplProc} Mf # A key binding ('ctrl-m i') to convert gf file to dv<i> : Bind 'i' <M> {Mf::otherfilesProc "otherFiles" "convertGfToDvi"} Mf # A key binding ('ctrl-m k') to convert gf file to p<k> : Bind 'k' <M> {Mf::otherfilesProc "otherFiles" "convertGfToPk"} Mf # A key binding ('ctrl-m v') to <v>iew the d<v>i : Bind 'v' <M> {Mf::setnames [win::Current];Mf::viewdviProc} Mf ########## File Marking ############ ########## The "M" menu ############ # Marking is different in mf source files and in pl or vpl files. # # # In mf source files : # The 'def' and 'vardef' definitions are marked in the "M" menu (top right of # the current window). All the 'beginchar/endchar' groups will be marked too. # Even if you changed the name of these 'beginchar' routines in the mode # specific prefs : for instance, if you chose to call them "myfontchar" then # all the "myfontchar" instructions will be marked. # For a 'beginchar' instruction, the proc looks if there is a string at the # end of the line (usually describing the char being designed) : if yes mark # this string, if not then mark the 'beginchar' and its character code. # # # In property list files : # the LIGTABLE and FONTDIMEN arrays are marked as well as every character # dimensions data. proc Mf::MarkFile {} { global MfmodeVars global MFextfilename Mf::setnames [win::Current] if {$MFextfilename == ".mf"} { set bgnchar $MfmodeVars(userBeginchar) # First mark the defs and vardefs set end [maxPos] set pos [minPos] while {![catch {search -f 1 -r 1 -m 0 -i 0 "^def \[ _\\w\]*|^vardef \[ _\\w\]*" $pos} res]} { set start [lindex $res 0] set end [lindex $res 1] set txt [getText [pos::math $start - 1] $end] set pos [nextLineStart $start] set inds($txt) [lineStart [pos::math $start - 1]] } if {[info exists inds]} { foreach f [lsort [array names inds]] { set next [nextLineStart $inds($f)] setNamedMark $f $inds($f) $next $next } unset inds } # Then mark the 'beginchar' instructions set end [maxPos] set pos [minPos] while {![catch {eval [concat search -f 1 -r 1 -m 0 -i 0\ [list "^$bgnchar.*$"] $pos]} res]} { set start [lindex $res 0] set end [lindex $res 1] set txt [getText [pos::math $start - 1] $end] if {[regexp "$bgnchar" $txt]} { if {![regexp {; ?\".*\" ?;} $txt txt]} { regexp "$bgnchar\[ _\\w\\d\\\(\\\"\]*" $txt txt set txt "$txt)" } else { set txt [string trim $txt ";\""] } } set pos [nextLineStart $start] set inds($txt) [lineStart [pos::math $start - 1]] } if {[info exists inds]} { foreach f [lsort [array names inds]] { set next [nextLineStart $inds($f)] setNamedMark $f $inds($f) $next $next } } } else { set pos [minPos] set end [maxPos] while {} $pos} res]} { set start [lindex $res 0] set end [lindex $res 1] set txt [getText [pos::math $start +1] $end] set pos [nextLineStart $start] set inds($txt) [lineStart [pos::math $start - 1]] } if {[info exists inds]} { foreach f [array names inds] { set next [nextLineStart $inds($f)] setNamedMark $f $inds($f) $next $next } } set pos [minPos] set end [maxPos] while {![catch {search -f 1 -r 1 -m 0 -i 0 {^[\(]CHARACTER[ \w\d]*} $pos} res]} { set start [lindex $res 0] set end [lindex $res 1] set txt [getText [pos::math $start +1] $end] set pos [nextLineStart $start] set inds($txt) [lineStart [pos::math $start - 1]] } if {[info exists inds]} { foreach f [lsort -increasing [array names inds]] { set next [nextLineStart $inds($f)] setNamedMark $f $inds($f) $next $next } } } } ########## The "{}" menu ############ # The "{}" pop-up menu contains the functions defined in a source file. We # list here all the def and vardef definitions as well as the files input # with an "input" command. Here we 'lappend' twice on purpose because # ::parseFuncs general proc takes one out of two : proc Mf::parseFuncs {} { global funcExpr Mfparse set Mfparse 1 set pos [minPos] set m {} while {[set res [search -s -f 1 -r 1 -i 0 -n "$funcExpr" $pos]] != ""} { lappend m [eval getText $res] lappend m [eval getText $res] set pos [lindex $res 1] } if {[expr {[lsearch -regexp $m "^(def|primarydef|secondarydef|tertiarydef) "] > -1}]} {lappend m "DEF :" ; lappend m "DEF :"} if {[expr {[lsearch -regexp $m "^vardef "] > -1}]} {lappend m "VARDEF :" ; lappend m "VARDEF :"} set m [lsort -ignore $m] set f [lsort -ignore [Mf::findInputFiles]] if {[llength $f]} { set f [linsert $f 0 "INPUT FILES : " "INPUT FILES : "] set m [linsert $m 0 "(-" "(-"] } return [concat $f $m] } proc Mf::findInputFiles {} { global Mfparse set files {} set pos [minPos] while {[set res [search -s -f 1 -r 1 -i 0 -n {^.*input.+$} $pos]] != ""} { set txt [eval getText $res] if {![regexp {^\%} $txt]} { regsub -all "(^.*input +)" $txt "" txt regsub -all " .+" $txt "" txt lappend files $txt if {$Mfparse} {lappend files $txt} } set pos [lindex $res 1] } set Mfparse 0 return $files } ########## Double-click ############ # If you Command-Double-Click on a keyword you access its definition. This # proc looks first for a definition in the current file itself, then in the # list of primitives, then in the plain Metafont macros file and finally in # the other text files located in the same folder and called in the current # file by an input command (typically they are macros files). set Mfinternals [list "blacker" "currentwindow" "displaying" "eps" "epsilon" \ "infinity" "join_radius" "number_of_modes" "o_correction" "pair" "path" "pen_bot"\ "pen_lft" "pen_rt" "pen_top" "pixels_per_inch" "screen_cols" "screen_rows" "tolerance" ] # set Mfconstants [list "basename" "base_version" "blankpicture" "currentpen"\ # "currentpen_path" "currenttransform" "ditto" "extra_beginchar" "extra_endchar"\ # "extra_setup" "fullcircle" "halfcircle" "identity" "mode_name" "penspeck"\ # "quartercircle" "rulepen" "unitpixel" "unitsquare" ] proc Mf::DblClick {from to} { global MfmodeVars pathToPlainMfFile Mfprimlist Mfparse Mfinternals # global Mfconstants select $from $to set word [getText $from $to] set Mfparse 0 # First we look for the word's definition in the current file : set pos [minPos] if {![catch {eval [concat search -f 1 -r 1 -m 1 -i 0\ [list "\(var|primary|secondary|tertiary\)?def\[ \\w\]+$word"] $pos]} res]} { goto [lineStart [lindex $res 0]] select [lindex $res 0] [lindex $res 1] return } # If search failed, check if it is a Metafont primitive. if {[expr {[lsearch -exact $Mfprimlist "$word"] > -1}]} { alertnote "\"$word\" is a Metafont primitive.\rSee the MetafontBook." return } # If search failed, check if it is a 'newinternal'. if {[expr {[lsearch -exact $Mfinternals "$word"] > -1}]} { alertnote "\"$word\" is a constant of type \"newinternal\".\rSee the MetafontBook or Metapost User's Manual." return } # If search failed, look in the plain.mf macros file. Its path must # have been defined in the mode prefs. set f $MfmodeVars(pathToPlainMfFile) if {![file exists $f]} { alertnote "Can't find file plain.mf : where is it ?" catch {getfile "Find file plain.mf"} chemin if {$chemin == ""} {return} removeArrDef MfmodeVars pathToPlainMfFile set pathToPlainMfFile $chemin set MfmodeVars(pathToPlainMfFile) [set chemin] addArrDef MfmodeVars pathToPlainMfFile $chemin } set cid [scancontext create] set searchstri "(var|primary|secondary|tertiary)?def\[ \\w\]+$word\[^\\w\]+" set searchstrii "(path|pen|picture|string|transform)\[ ,\\w\]+$word" scanmatch -- $cid $searchstri {set matches($f) 1} scanmatch -- $cid $searchstrii {set matches($f) 1} if {![catch {set fid [open $f]}]} { message "Looking at '[file tail $f]'" scanfile $cid $fid close $fid } if {[info exists matches]} { Mf::BringOrEdit $MfmodeVars(pathToPlainMfFile) -r goto $matchInfo(offset) set res [search -s -f 1 -r 0 -i 0 -m 1 -n $word $matchInfo(offset)] select $matchInfo(offset)] [lindex $res 1] unset matches return } # As a last resort, we search all the input files found in the source file provided # they are located in the same folder as the current file. set f [Mf::findInputFiles] if {[llength $f]} { foreach filetail $f { set filetail [string trim $filetail ".mf"] set fullname [file join [file dirname [win::Current]] $filetail.mf] if {[file exists $fullname]} { if {![catch {set fid [open $fullname]}]} { message "Looking at '$filetail'" scanfile $cid $fid close $fid } } if {[info exists matches]} { Mf::BringOrEdit $fullname -r goto $matchInfo(offset) set res [search -s -f 1 -r 0 -i 0 -n $word $matchInfo(offset)] select $matchInfo(offset) [lindex $res 1] return } } } scancontext delete $cid beep message "Could'nt find a definition for \"$word\"." } ########## Option-click on title bar ############ # If you Option-Click on a the title bar, you get a list of all the mf and # log files located : # - in the "local" folder (folder of currentwindow). # - in the "selected" folder (selected when you process an entire folder with # "Run A Folder" or in the "Remove Files" sub menu) # Selecting any item will open it in a window or bring its window to front if # it is already open. proc Mf::OptionTitlebar {} { global MFcurrentdir sep minItemsInTitlePopup set minItemsInTitlePopup 1 set sep "-" set filesinlocaldir [glob -nocomplain -dir [file dirname [win::Current]] *.mf] set logsinlocaldir [glob -nocomplain -dir [file dirname [win::Current]] *.log] set filesinselecteddir {} set logsinselecteddir {} if {$MFcurrentdir !="" && $MFcurrentdir!=[file dirname [win::Current]]} { set filesinselecteddir [glob -nocomplain -dir $MFcurrentdir *.mf] set logsinselecteddir [glob -nocomplain -dir $MFcurrentdir *.log] } set l {} foreach f $filesinlocaldir { lappend l [file tail $f] } foreach dir [list filesinselecteddir logsinlocaldir logsinselecteddir] { eval [concat "if \{\[llength \$$dir\]\} \{lappend l \$sep ; \ foreach f \$$dir \{lappend l \[file tail \$f\]\}\}"] } return $l } proc Mf::OptionTitlebarSelect {item} { global MFcurrentdir sep if {$item == $sep} {return} if {[file exists [file join [file dirname [win::Current]] $item]]} { Mf::BringOrEdit [file join [file dirname [win::Current]] $item] -c } else { Mf::BringOrEdit [file join $MFcurrentdir $item] -c } } proc Mf::BringOrEdit {name {type ""}} { catch {lsearch -exact [winNames] [file tail $name]} indx if {[expr {$indx > -1}]} { bringToFront [file tail $name] } else { edit $type $name } } # Send comments to : # <berdesg@easynet.fr>